From 24e4a1211f691fc671de44685430dbad757d8487 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Apr 2010 11:22:01 +0200 Subject: ALSA: info - Use standard types for info callbacks Use loff_t, size_t and ssize_t for arguments of info callbacks to follow the standard procfs. Signed-off-by: Takashi Iwai --- sound/isa/gus/gus_mem_proc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index 2803e227aec9..b2d2dba6c860 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -31,9 +31,10 @@ struct gus_proc_private { struct snd_gus_card * gus; }; -static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct gus_proc_private *priv = entry->private_data; @@ -51,11 +52,10 @@ static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_priva return 0; } -static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) +static loff_t snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, + void *private_file_data, + struct file *file, + loff_t offset, int orig) { struct gus_proc_private *priv = entry->private_data; -- cgit v1.2.3 From d97e1b78239c7e7e441088e0b644bd3b076002e6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Apr 2010 11:33:54 +0200 Subject: ALSA: info - Check file position validity in common layer Check the validity of the file position in the common info layer before calling read or write callbacks in assumption that entry->size is set up properly to indicate the max file size. Removed the redundant checks from the callbacks as well. Signed-off-by: Takashi Iwai --- sound/core/info.c | 14 ++++++++++--- sound/drivers/opl4/opl4_proc.c | 46 +++++++++++++++--------------------------- sound/isa/gus/gus_mem_proc.c | 14 ++++--------- sound/pci/cs4281.c | 24 ++++++---------------- sound/pci/cs46xx/cs46xx_lib.c | 12 +++-------- sound/pci/emu10k1/emuproc.c | 43 ++++++++++++++++++--------------------- sound/pci/mixart/mixart.c | 12 ----------- 7 files changed, 60 insertions(+), 105 deletions(-) (limited to 'sound/isa') diff --git a/sound/core/info.c b/sound/core/info.c index ff968be81678..f90a6fd43fb4 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -232,10 +232,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, return -EFAULT; break; case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->read) + if (pos >= entry->size) + return 0; + if (entry->c.ops->read) { + size = entry->size - pos; + size = min(count, size); size = entry->c.ops->read(entry, data->file_private_data, - file, buffer, count, pos); + file, buffer, size, pos); + } break; } if ((ssize_t) size > 0) @@ -282,10 +287,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer size = count; break; case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->write) + if (entry->c.ops->write && count > 0) { + size_t maxsize = entry->size - pos; + count = min(count, maxsize); size = entry->c.ops->write(entry, data->file_private_data, file, buffer, count, pos); + } break; } if ((ssize_t) size > 0) diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index eb72814dfd5f..210b89de06d7 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c @@ -55,25 +55,18 @@ static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry, size_t count, loff_t pos) { struct snd_opl4 *opl4 = entry->private_data; - long size; char* buf; - size = count; - if (pos + size > entry->size) - size = entry->size - pos; - if (size > 0) { - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - snd_opl4_read_memory(opl4, buf, pos, size); - if (copy_to_user(_buf, buf, size)) { - vfree(buf); - return -EFAULT; - } + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + snd_opl4_read_memory(opl4, buf, pos, count); + if (copy_to_user(_buf, buf, count)) { vfree(buf); - return size; + return -EFAULT; } - return 0; + vfree(buf); + return count; } static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, @@ -83,25 +76,18 @@ static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, size_t count, size_t pos) { struct snd_opl4 *opl4 = entry->private_data; - long size; char *buf; - size = count; - if (pos + size > entry->size) - size = entry->size - pos; - if (size > 0) { - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, _buf, size)) { - vfree(buf); - return -EFAULT; - } - snd_opl4_write_memory(opl4, buf, pos, size); + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + if (copy_from_user(buf, _buf, count)) { vfree(buf); - return size; + return -EFAULT; } - return 0; + snd_opl4_write_memory(opl4, buf, pos, count); + vfree(buf); + return count; } static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index b2d2dba6c860..faa2bec8f6b6 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -36,20 +36,14 @@ static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, struct file *file, char __user *buf, size_t count, loff_t pos) { - long size; struct gus_proc_private *priv = entry->private_data; struct snd_gus_card *gus = priv->gus; int err; - size = count; - if (pos + size > priv->size) - size = (long)priv->size - pos; - if (size > 0) { - if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0) - return err; - return size; - } - return 0; + err = snd_gus_dram_read(gus, buf, pos, count, priv->rom); + if (err < 0) + return err; + return count; } static loff_t snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index b0bba2e86b12..6772070ed492 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1144,17 +1144,11 @@ static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry, struct file *file, char __user *buf, size_t count, loff_t pos) { - long size; struct cs4281 *chip = entry->private_data; - size = count; - if (pos + size > CS4281_BA0_SIZE) - size = (long)CS4281_BA0_SIZE - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, chip->ba0 + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, chip->ba0 + pos, count)) + return -EFAULT; + return count; } static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry, @@ -1162,17 +1156,11 @@ static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry, struct file *file, char __user *buf, size_t count, loff_t pos) { - long size; struct cs4281 *chip = entry->private_data; - size = count; - if (pos + size > CS4281_BA1_SIZE) - size = (long)CS4281_BA1_SIZE - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, chip->ba1 + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, chip->ba1 + pos, count)) + return -EFAULT; + return count; } static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = { diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 08117b142381..aad37082cb6e 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -2662,17 +2662,11 @@ static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry, struct file *file, char __user *buf, size_t count, loff_t pos) { - long size; struct snd_cs46xx_region *region = entry->private_data; - size = count; - if (pos + (size_t)size > region->size) - size = region->size - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, region->remap_addr + pos, count)) + return -EFAULT; + return count; } static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index 347b2415db59..bc38dd4d071f 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -346,10 +346,12 @@ static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry, struct file *file, char __user *buf, size_t count, loff_t pos) { - long size; struct snd_emu10k1 *emu = entry->private_data; unsigned int offset; int tram_addr = 0; + unsigned int *tmp; + long res; + unsigned int idx; if (!strcmp(entry->name, "fx8010_tram_addr")) { offset = TANKMEMADDRREGBASE; @@ -361,30 +363,25 @@ static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry, } else { offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; } - size = count; - if (pos + size > entry->size) - size = (long)entry->size - pos; - if (size > 0) { - unsigned int *tmp; - long res; - unsigned int idx; - if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) - return -ENOMEM; - for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) - if (tram_addr && emu->audigy) { - tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11; - tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20; - } else - tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0); - if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size)) - res = -EFAULT; - else { - res = size; + + tmp = kmalloc(count + 8, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) { + unsigned int val; + val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0); + if (tram_addr && emu->audigy) { + val >>= 11; + val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20; } - kfree(tmp); - return res; + tmp[idx] = val; } - return 0; + if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count)) + res = -EFAULT; + else + res = count; + kfree(tmp); + return res; } static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index b5df78bcc25b..be95e005c81d 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1161,13 +1161,7 @@ static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry, size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; - unsigned long maxsize; - if (pos >= MIXART_BA0_SIZE) - return 0; - maxsize = MIXART_BA0_SIZE - pos; - if (count > maxsize) - count = maxsize; count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) return -EFAULT; @@ -1183,13 +1177,7 @@ static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry, size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; - unsigned long maxsize; - if (pos > MIXART_BA1_SIZE) - return 0; - maxsize = MIXART_BA1_SIZE - pos; - if (count > maxsize) - count = maxsize; count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) return -EFAULT; -- cgit v1.2.3 From 73029e0ff18dfac8a1aab1dc188e1e150bbe3adc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Apr 2010 11:39:47 +0200 Subject: ALSA: info - Implement common llseek for binary mode The llseek implementation is identical for existing driver implementations, so let's merge to the common layer. The same code for the text proc file can be used even for the binary proc file. The driver can provide its own llseek method if needed. Then the common code will be skipped. Signed-off-by: Takashi Iwai --- sound/core/info.c | 56 ++++++++++++++++++++++-------------------- sound/drivers/opl4/opl4_proc.c | 24 ------------------ sound/isa/gus/gus_mem_proc.c | 26 -------------------- sound/pci/mixart/mixart.c | 51 -------------------------------------- 4 files changed, 30 insertions(+), 127 deletions(-) (limited to 'sound/isa') diff --git a/sound/core/info.c b/sound/core/info.c index f90a6fd43fb4..b70564ed8b37 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -164,39 +164,43 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) { struct snd_info_private_data *data; struct snd_info_entry *entry; - loff_t ret; + loff_t ret = -EINVAL, size; data = file->private_data; entry = data->entry; mutex_lock(&entry->access); - switch (entry->content) { - case SNDRV_INFO_CONTENT_TEXT: - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - ret = file->f_pos; - goto out; - case SEEK_CUR: - file->f_pos += offset; - ret = file->f_pos; - goto out; - case SEEK_END: - default: - ret = -EINVAL; - goto out; - } + if (entry->content == SNDRV_INFO_CONTENT_DATA && + entry->c.ops->llseek) { + offset = entry->c.ops->llseek(entry, + data->file_private_data, + file, offset, orig); + goto out; + } + if (entry->content == SNDRV_INFO_CONTENT_DATA) + size = entry->size; + else + size = 0; + switch (orig) { + case SEEK_SET: break; - case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->llseek) { - ret = entry->c.ops->llseek(entry, - data->file_private_data, - file, offset, orig); + case SEEK_CUR: + offset += file->f_pos; + break; + case SEEK_END: + if (!size) goto out; - } + offset += size; break; - } - ret = -ENXIO; -out: + default: + goto out; + } + if (offset < 0) + goto out; + if (size && offset > size) + offset = size; + file->f_pos = offset; + ret = offset; + out: mutex_unlock(&entry->access); return ret; } diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index 210b89de06d7..c5c13c4c260e 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c @@ -90,35 +90,11 @@ static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, return count; } -static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, - loff_t offset, int orig) -{ - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = entry->size + offset; - break; - default: - return -EINVAL; - } - if (file->f_pos > entry->size) - file->f_pos = entry->size; - return file->f_pos; -} - static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { .open = snd_opl4_mem_proc_open, .release = snd_opl4_mem_proc_release, .read = snd_opl4_mem_proc_read, .write = snd_opl4_mem_proc_write, - .llseek = snd_opl4_mem_proc_llseek, }; int snd_opl4_create_proc(struct snd_opl4 *opl4) diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index faa2bec8f6b6..2ccb3fadd7be 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -46,31 +46,6 @@ static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, return count; } -static loff_t snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - loff_t offset, int orig) -{ - struct gus_proc_private *priv = entry->private_data; - - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = priv->size + offset; - break; - default: - return -EINVAL; - } - if (file->f_pos > priv->size) - file->f_pos = priv->size; - return file->f_pos; -} - static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) { struct gus_proc_private *priv = entry->private_data; @@ -79,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { .read = snd_gf1_mem_proc_dump, - .llseek = snd_gf1_mem_proc_llseek, }; int snd_gf1_mem_proc_init(struct snd_gus_card * gus) diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index be95e005c81d..6c3fd4d1c49d 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1102,55 +1102,6 @@ static int snd_mixart_free(struct mixart_mgr *mgr) /* * proc interface */ -static loff_t snd_mixart_BA0_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - loff_t offset, int orig) -{ - offset = offset & ~3; /* 4 bytes aligned */ - - switch(orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = MIXART_BA0_SIZE + offset; - break; - default: - return -EINVAL; - } - if(file->f_pos > MIXART_BA0_SIZE) - file->f_pos = MIXART_BA0_SIZE; - return file->f_pos; -} - -static loff_t snd_mixart_BA1_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - loff_t offset, int orig) -{ - offset = offset & ~3; /* 4 bytes aligned */ - - switch(orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = MIXART_BA1_SIZE + offset; - break; - default: - return -EINVAL; - } - if(file->f_pos > MIXART_BA1_SIZE) - file->f_pos = MIXART_BA1_SIZE; - return file->f_pos; -} /* mixart_BA0 proc interface for BAR 0 - read callback @@ -1186,12 +1137,10 @@ static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry, static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { .read = snd_mixart_BA0_read, - .llseek = snd_mixart_BA0_llseek }; static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { .read = snd_mixart_BA1_read, - .llseek = snd_mixart_BA1_llseek }; -- cgit v1.2.3 From 867f1845c53f52e6b9822bea387c7b16740ba2f8 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 25 Apr 2010 13:12:45 +0200 Subject: ALSA: es968: fix wrong PnP dma index There is only one dma for the ESS ES968 based board. Its index is 0 and not 1. This make the es968 card working. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- sound/isa/sb/es968.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/isa') diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index cafc3a7316a8..ff18286fef9d 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c @@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, return err; } port[dev] = pnp_port_start(pdev, 0); - dma8[dev] = pnp_dma(pdev, 1); + dma8[dev] = pnp_dma(pdev, 0); irq[dev] = pnp_irq(pdev, 0); return 0; -- cgit v1.2.3 From 396fa8272601c3d488cb8391c3962a7ee552afd0 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 9 May 2010 20:35:44 +0200 Subject: ALSA: es1688: allocate snd_es1688 structure as a part of snd_card structure Allocate the snd_es1688 during the snd_card allocation. This allows to remove the card pointer from the snd_es1688 structure. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- include/sound/es1688.h | 10 +++++----- sound/isa/es1688/es1688.c | 23 ++++++++++++---------- sound/isa/es1688/es1688_lib.c | 44 ++++++++++++++----------------------------- sound/isa/gus/gusextreme.c | 26 +++++++++++++------------ 4 files changed, 46 insertions(+), 57 deletions(-) (limited to 'sound/isa') diff --git a/include/sound/es1688.h b/include/sound/es1688.h index 10fcf1465810..4c29572effb2 100644 --- a/include/sound/es1688.h +++ b/include/sound/es1688.h @@ -44,7 +44,6 @@ struct snd_es1688 { unsigned char pad; unsigned int dma_size; - struct snd_card *card; struct snd_pcm *pcm; struct snd_pcm_substream *playback_substream; struct snd_pcm_substream *capture_substream; @@ -108,14 +107,15 @@ struct snd_es1688 { void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data); int snd_es1688_create(struct snd_card *card, + struct snd_es1688 *chip, unsigned long port, unsigned long mpu_port, int irq, int mpu_irq, int dma8, - unsigned short hardware, - struct snd_es1688 ** rchip); -int snd_es1688_pcm(struct snd_es1688 *chip, int device, struct snd_pcm ** rpcm); -int snd_es1688_mixer(struct snd_es1688 *chip); + unsigned short hardware); +int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device, + struct snd_pcm **rpcm); +int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip); #endif /* __SOUND_ES1688_H */ diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 07df201ed8fa..281679493fb4 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -79,8 +79,8 @@ static int __devinit snd_es1688_match(struct device *dev, unsigned int n) return enable[n]; } -static int __devinit snd_es1688_legacy_create(struct snd_card *card, - struct device *dev, unsigned int n, struct snd_es1688 **rchip) +static int __devinit snd_es1688_legacy_create(struct snd_card *card, + struct snd_es1688 *chip, struct device *dev, unsigned int n) { static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; @@ -104,14 +104,14 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card, } if (port[n] != SNDRV_AUTO_PORT) - return snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + return snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO); i = 0; do { port[n] = possible_ports[i]; - error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + error = snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO); } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); return error; @@ -125,19 +125,22 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); if (error < 0) return error; - error = snd_es1688_legacy_create(card, dev, n, &chip); + chip = card->private_data; + + error = snd_es1688_legacy_create(card, chip, dev, n); if (error < 0) goto out; - error = snd_es1688_pcm(chip, 0, &pcm); + error = snd_es1688_pcm(card, chip, 0, &pcm); if (error < 0) goto out; - error = snd_es1688_mixer(chip); + error = snd_es1688_mixer(card, chip); if (error < 0) goto out; diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index c76bb00c9d15..fdd440417bf0 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -620,7 +620,6 @@ static int snd_es1688_free(struct snd_es1688 *chip) disable_dma(chip->dma8); free_dma(chip->dma8); } - kfree(chip); return 0; } @@ -638,23 +637,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip) } int snd_es1688_create(struct snd_card *card, + struct snd_es1688 *chip, unsigned long port, unsigned long mpu_port, int irq, int mpu_irq, int dma8, - unsigned short hardware, - struct snd_es1688 **rchip) + unsigned short hardware) { static struct snd_device_ops ops = { .dev_free = snd_es1688_dev_free, }; - struct snd_es1688 *chip; int err; - *rchip = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->irq = -1; @@ -662,25 +658,21 @@ int snd_es1688_create(struct snd_card *card, if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); - snd_es1688_free(chip); return -EBUSY; } if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); - snd_es1688_free(chip); return -EBUSY; } chip->irq = irq; if (request_dma(dma8, "ES1688")) { snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); - snd_es1688_free(chip); return -EBUSY; } chip->dma8 = dma8; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->mixer_lock); - chip->card = card; chip->port = port; mpu_port &= ~0x000f; if (mpu_port < 0x300 || mpu_port > 0x330) @@ -689,23 +681,16 @@ int snd_es1688_create(struct snd_card *card, chip->mpu_irq = mpu_irq; chip->hardware = hardware; - if ((err = snd_es1688_probe(chip)) < 0) { - snd_es1688_free(chip); + err = snd_es1688_probe(chip); + if (err < 0) return err; - } - if ((err = snd_es1688_init(chip, 1)) < 0) { - snd_es1688_free(chip); - return err; - } - /* Register device */ - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_es1688_free(chip); + err = snd_es1688_init(chip, 1); + if (err < 0) return err; - } - *rchip = chip; - return 0; + /* Register device */ + return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); } static struct snd_pcm_ops snd_es1688_playback_ops = { @@ -730,12 +715,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = { .pointer = snd_es1688_capture_pointer, }; -int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) +int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, + int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) + err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm); + if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); @@ -1009,18 +996,15 @@ static unsigned char snd_es1688_init_table[][2] = { { ES1688_REC_DEV, 0x17 } }; -int snd_es1688_mixer(struct snd_es1688 *chip) +int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip) { - struct snd_card *card; unsigned int idx; int err; unsigned char reg, val; - if (snd_BUG_ON(!chip || !chip->card)) + if (snd_BUG_ON(!chip || !card)) return -EINVAL; - card = chip->card; - strcpy(card->mixername, snd_es1688_chip_id(chip)); for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 65e4b18581a6..008e8e5bfa37 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n) } static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, - struct device *dev, unsigned int n, struct snd_es1688 **rchip) + struct snd_es1688 *chip, struct device *dev, unsigned int n) { static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; @@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, } if (port[n] != SNDRV_AUTO_PORT) - return snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + return snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); i = 0; do { port[n] = possible_ports[i]; - error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + error = snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); return error; @@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus, return 0; } -static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) +static int __devinit snd_gusextreme_mixer(struct snd_card *card) { - struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; int error; @@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) struct snd_opl3 *opl3; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); if (error < 0) return error; + es1688 = card->private_data; + if (mpu_port[n] == SNDRV_AUTO_PORT) mpu_port[n] = 0; if (mpu_irq[n] > 15) mpu_irq[n] = -1; - error = snd_gusextreme_es1688_create(card, dev, n, &es1688); + error = snd_gusextreme_es1688_create(card, es1688, dev, n); if (error < 0) goto out; @@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) } gus->codec_flag = 1; - error = snd_es1688_pcm(es1688, 0, NULL); + error = snd_es1688_pcm(card, es1688, 0, NULL); if (error < 0) goto out; - error = snd_es1688_mixer(es1688); + error = snd_es1688_mixer(card, es1688); if (error < 0) goto out; @@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - error = snd_gusextreme_mixer(es1688); + error = snd_gusextreme_mixer(card); if (error < 0) goto out; -- cgit v1.2.3 From a20971b201ac1fcd236400942c98b0106c42c70a Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Mon, 10 May 2010 09:47:32 +0200 Subject: ALSA: Merge es1688 and es968 drivers The ESS ES968 chip is nothing more then a PnP companion for a non-PnP audio chip. It was paired with non-PnP ESS' chips: ES688 and ES1688. The ESS' audio chips are handled by the es1688 driver in native mode. The PnP cards are handled by the ES968 driver in SB compatible mode. Move the ES968 chip handling to the es1688 driver so the driver can handle both PnP and non-PnP cards. The es968 is removed. Also, a new PnP id is added for the card I acquired (the change was tested on this card). Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 21 +- include/sound/es1688.h | 1 + sound/isa/Kconfig | 16 +- sound/isa/es1688/es1688.c | 205 +++++++++++++++++--- sound/isa/es1688/es1688_lib.c | 3 +- sound/isa/sb/Makefile | 2 - sound/isa/sb/es968.c | 248 ------------------------ 7 files changed, 190 insertions(+), 306 deletions(-) delete mode 100644 sound/isa/sb/es968.c (limited to 'sound/isa') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index dc681badca67..2075bbb8b3e2 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -632,28 +632,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - Module snd-es968 - ---------------- - - Module for sound cards based on ESS ES968 chip (PnP only). - - This module supports multiple cards, PnP and autoprobe. - - The power-management is supported. - Module snd-es1688 ----------------- Module for ESS AudioDrive ES-1688 and ES-688 sound cards. - port - port # for ES-1688 chip (0x220,0x240,0x260) - fm_port - port # for OPL3 (option; share the same port as default) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) - irq - IRQ # for ES-1688 chip (5,7,9,10) mpu_irq - IRQ # for MPU-401 port (5,7,9,10) + fm_port - port # for OPL3 (option; share the same port as default) + + with isapnp=0, the following additional options are available: + port - port # for ES-1688 chip (0x220,0x240,0x260) + irq - IRQ # for ES-1688 chip (5,7,9,10) dma8 - DMA # for ES-1688 chip (0,1,3) - This module supports multiple cards and autoprobe (without MPU-401 port). + This module supports multiple cards and autoprobe (without MPU-401 port) + and PnP with the ES968 chip. Module snd-es18xx ----------------- diff --git a/include/sound/es1688.h b/include/sound/es1688.h index 4c29572effb2..3ec7ecbe2502 100644 --- a/include/sound/es1688.h +++ b/include/sound/es1688.h @@ -117,5 +117,6 @@ int snd_es1688_create(struct snd_card *card, int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device, struct snd_pcm **rpcm); int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip); +int snd_es1688_reset(struct snd_es1688 *chip); #endif /* __SOUND_ES1688_H */ diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 755a0a5f0e3f..c6990c680796 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -128,26 +128,14 @@ config SND_CS4236 To compile this driver as a module, choose M here: the module will be called snd-cs4236. -config SND_ES968 - tristate "Generic ESS ES968 driver" - depends on PNP - select ISAPNP - select SND_MPU401_UART - select SND_SB8_DSP - help - Say Y here to include support for ESS AudioDrive ES968 chips. - - To compile this driver as a module, choose M here: the module - will be called snd-es968. - config SND_ES1688 - tristate "Generic ESS ES688/ES1688 driver" + tristate "Generic ESS ES688/ES1688 and ES968 PnP driver" select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM help Say Y here to include support for ESS AudioDrive ES688 or - ES1688 chips. + ES1688 chips. Also, this module support cards with ES968 PnP chip. To compile this driver as a module, choose M here: the module will be called snd-es1688. diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 281679493fb4..fdcce311f80a 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," "{ESS,ES688 AudioDrive,pnp:ESS6881}," "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); +MODULE_ALIAS("snd_es968"); + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ +#ifdef CONFIG_PNP +static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; +#endif static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ @@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); +#ifdef CONFIG_PNP +module_param_array(isapnp, bool, NULL, 0444); +MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); +#endif MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); @@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); +#ifdef CONFIG_PNP +#define is_isapnp_selected(dev) isapnp[dev] +#else +#define is_isapnp_selected(dev) 0 +#endif + static int __devinit snd_es1688_match(struct device *dev, unsigned int n) { - return enable[n]; + return enable[n] && !is_isapnp_selected(n); } static int __devinit snd_es1688_legacy_create(struct snd_card *card, - struct snd_es1688 *chip, struct device *dev, unsigned int n) + struct device *dev, unsigned int n) { + struct snd_es1688 *chip = card->private_data; static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas[] = {1, 3, 0, -1}; @@ -117,32 +134,20 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card, return error; } -static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) +static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n) { - struct snd_card *card; - struct snd_es1688 *chip; + struct snd_es1688 *chip = card->private_data; struct snd_opl3 *opl3; struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, - sizeof(struct snd_es1688), &card); - if (error < 0) - return error; - - chip = card->private_data; - - error = snd_es1688_legacy_create(card, chip, dev, n); - if (error < 0) - goto out; - error = snd_es1688_pcm(card, chip, 0, &pcm); if (error < 0) - goto out; + return error; error = snd_es1688_mixer(card, chip); if (error < 0) - goto out; + return error; strcpy(card->driver, "ES1688"); strcpy(card->shortname, pcm->name); @@ -155,12 +160,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) if (fm_port[n] > 0) { if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, OPL3_HW_OPL3, 0, &opl3) < 0) - dev_warn(dev, + dev_warn(card->dev, "opl3 not detected at 0x%lx\n", fm_port[n]); else { error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); if (error < 0) - goto out; + return error; } } @@ -170,23 +175,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) chip->mpu_port, 0, mpu_irq[n], IRQF_DISABLED, NULL); if (error < 0) - goto out; + return error; } + return snd_card_register(card); +} + +static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n) +{ + struct snd_card *card; + int error; + + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); + if (error < 0) + return error; + + error = snd_es1688_legacy_create(card, dev, n); + if (error < 0) + goto out; + snd_card_set_dev(card, dev); - error = snd_card_register(card); + error = snd_es1688_probe(card, n); if (error < 0) goto out; dev_set_drvdata(dev, card); - return 0; -out: snd_card_free(card); + return 0; +out: + snd_card_free(card); return error; } -static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) +static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n) { snd_card_free(dev_get_drvdata(dev)); dev_set_drvdata(dev, NULL); @@ -195,8 +218,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) static struct isa_driver snd_es1688_driver = { .match = snd_es1688_match, - .probe = snd_es1688_probe, - .remove = __devexit_p(snd_es1688_remove), + .probe = snd_es1688_isa_probe, + .remove = __devexit_p(snd_es1688_isa_remove), #if 0 /* FIXME */ .suspend = snd_es1688_suspend, .resume = snd_es1688_resume, @@ -206,14 +229,140 @@ static struct isa_driver snd_es1688_driver = { } }; +static int snd_es968_pnp_is_probed; + +#ifdef CONFIG_PNP +static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n, + struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) +{ + struct snd_es1688 *chip = card->private_data; + struct pnp_dev *pdev; + int error; + + pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); + if (pdev == NULL) + return -ENODEV; + + error = pnp_activate_dev(pdev); + if (error < 0) { + snd_printk(KERN_ERR "ES968 pnp configure failure\n"); + return error; + } + port[n] = pnp_port_start(pdev, 0); + dma8[n] = pnp_dma(pdev, 0); + irq[n] = pnp_irq(pdev, 0); + + return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO); +} + +static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) +{ + struct snd_card *card; + static unsigned int dev; + int error; + struct snd_es1688 *chip; + + if (snd_es968_pnp_is_probed) + return -EBUSY; + for ( ; dev < SNDRV_CARDS; dev++) { + if (enable[dev] && isapnp[dev]) + break; + } + + error = snd_card_create(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_es1688), &card); + if (error < 0) + return error; + chip = card->private_data; + + error = snd_card_es968_pnp(card, dev, pcard, pid); + if (error < 0) { + snd_card_free(card); + return error; + } + snd_card_set_dev(card, &pcard->card->dev); + error = snd_es1688_probe(card, dev); + if (error < 0) + return error; + pnp_set_card_drvdata(pcard, card); + snd_es968_pnp_is_probed = 1; + return 0; +} + +static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) +{ + snd_card_free(pnp_get_card_drvdata(pcard)); + pnp_set_card_drvdata(pcard, NULL); + snd_es968_pnp_is_probed = 0; +} + +#ifdef CONFIG_PM +static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, + pm_message_t state) +{ + struct snd_card *card = pnp_get_card_drvdata(pcard); + struct snd_es1688 *chip = card->private_data; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + return 0; +} + +static int snd_es968_pnp_resume(struct pnp_card_link *pcard) +{ + struct snd_card *card = pnp_get_card_drvdata(pcard); + struct snd_es1688 *chip = card->private_data; + + snd_es1688_reset(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +static struct pnp_card_device_id snd_es968_pnpids[] = { + { .id = "ESS0968", .devs = { { "@@@0968" }, } }, + { .id = "ESS0968", .devs = { { "ESS0968" }, } }, + { .id = "", } /* end */ +}; + +MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); + +static struct pnp_card_driver es968_pnpc_driver = { + .flags = PNP_DRIVER_RES_DISABLE, + .name = DEV_NAME " PnP", + .id_table = snd_es968_pnpids, + .probe = snd_es968_pnp_detect, + .remove = __devexit_p(snd_es968_pnp_remove), +#ifdef CONFIG_PM + .suspend = snd_es968_pnp_suspend, + .resume = snd_es968_pnp_resume, +#endif +}; +#endif + static int __init alsa_card_es1688_init(void) { +#ifdef CONFIG_PNP + pnp_register_card_driver(&es968_pnpc_driver); + if (snd_es968_pnp_is_probed) + return 0; + pnp_unregister_card_driver(&es968_pnpc_driver); +#endif return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); } static void __exit alsa_card_es1688_exit(void) { - isa_unregister_driver(&snd_es1688_driver); + if (!snd_es968_pnp_is_probed) { + isa_unregister_driver(&snd_es1688_driver); + return; + } +#ifdef CONFIG_PNP + pnp_unregister_card_driver(&es968_pnpc_driver); +#endif } module_init(alsa_card_es1688_init); diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index fdd440417bf0..07676200496a 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha return result; } -static int snd_es1688_reset(struct snd_es1688 *chip) +int snd_es1688_reset(struct snd_es1688 *chip) { int i; @@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip) snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ return 0; } +EXPORT_SYMBOL(snd_es1688_reset); static int snd_es1688_probe(struct snd_es1688 *chip) { diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index af3669681788..08b9fb974658 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o snd-sb16-objs := sb16.o snd-sbawe-objs := sbawe.o emu8000.o snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o -snd-es968-objs := es968.o snd-jazz16-objs := jazz16.o # Toplevel Module Dependency @@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o obj-$(CONFIG_SND_SB8) += snd-sb8.o obj-$(CONFIG_SND_SB16) += snd-sb16.o obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o -obj-$(CONFIG_SND_ES968) += snd-es968.o obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c deleted file mode 100644 index ff18286fef9d..000000000000 --- a/sound/isa/sb/es968.c +++ /dev/null @@ -1,248 +0,0 @@ - -/* - card-es968.c - driver for ESS AudioDrive ES968 based soundcards. - Copyright (C) 1999 by Massimo Piccioni - - Thanks to Pierfrancesco 'qM2' Passerini. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#define PFX "es968: " - -MODULE_AUTHOR("Massimo Piccioni "); -MODULE_DESCRIPTION("ESS AudioDrive ES968"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ -static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ -static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ -static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for es968 based soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for es968 based soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable es968 based soundcard."); - -struct snd_card_es968 { - struct pnp_dev *dev; - struct snd_sb *chip; -}; - -static struct pnp_card_device_id snd_es968_pnpids[] = { - { .id = "ESS0968", .devs = { { "@@@0968" }, } }, - { .id = "", } /* end */ -}; - -MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); - -#define DRIVER_NAME "snd-card-es968" - -static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id) -{ - struct snd_sb *chip = dev_id; - - if (chip->open & SB_OPEN_PCM) { - return snd_sb8dsp_interrupt(chip); - } else { - return snd_sb8dsp_midi_interrupt(chip); - } -} - -static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, - struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - struct pnp_dev *pdev; - int err; - - acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); - if (acard->dev == NULL) - return -ENODEV; - - pdev = acard->dev; - - err = pnp_activate_dev(pdev); - if (err < 0) { - snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n"); - return err; - } - port[dev] = pnp_port_start(pdev, 0); - dma8[dev] = pnp_dma(pdev, 0); - irq[dev] = pnp_irq(pdev, 0); - - return 0; -} - -static int __devinit snd_card_es968_probe(int dev, - struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) -{ - int error; - struct snd_sb *chip; - struct snd_card *card; - struct snd_card_es968 *acard; - - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_es968), &card); - if (error < 0) - return error; - acard = card->private_data; - if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { - snd_card_free(card); - return error; - } - snd_card_set_dev(card, &pcard->card->dev); - - if ((error = snd_sbdsp_create(card, port[dev], - irq[dev], - snd_card_es968_interrupt, - dma8[dev], - -1, - SB_HW_AUTO, &chip)) < 0) { - snd_card_free(card); - return error; - } - acard->chip = chip; - - if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sbmixer_new(chip)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - strcpy(card->driver, "ES968"); - strcpy(card->shortname, "ESS ES968"); - sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d", - card->shortname, chip->name, chip->port, irq[dev], dma8[dev]); - - if ((error = snd_card_register(card)) < 0) { - snd_card_free(card); - return error; - } - pnp_set_card_drvdata(pcard, card); - return 0; -} - -static unsigned int __devinitdata es968_devices; - -static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - static int dev; - int res; - - for ( ; dev < SNDRV_CARDS; dev++) { - if (!enable[dev]) - continue; - res = snd_card_es968_probe(dev, card, id); - if (res < 0) - return res; - dev++; - es968_devices++; - return 0; - } - return -ENODEV; -} - -static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) -{ - snd_card_free(pnp_get_card_drvdata(pcard)); - pnp_set_card_drvdata(pcard, NULL); -} - -#ifdef CONFIG_PM -static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) -{ - struct snd_card *card = pnp_get_card_drvdata(pcard); - struct snd_card_es968 *acard = card->private_data; - struct snd_sb *chip = acard->chip; - - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_sbmixer_suspend(chip); - return 0; -} - -static int snd_es968_pnp_resume(struct pnp_card_link *pcard) -{ - struct snd_card *card = pnp_get_card_drvdata(pcard); - struct snd_card_es968 *acard = card->private_data; - struct snd_sb *chip = acard->chip; - - snd_sbdsp_reset(chip); - snd_sbmixer_resume(chip); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - -static struct pnp_card_driver es968_pnpc_driver = { - .flags = PNP_DRIVER_RES_DISABLE, - .name = "es968", - .id_table = snd_es968_pnpids, - .probe = snd_es968_pnp_detect, - .remove = __devexit_p(snd_es968_pnp_remove), -#ifdef CONFIG_PM - .suspend = snd_es968_pnp_suspend, - .resume = snd_es968_pnp_resume, -#endif -}; - -static int __init alsa_card_es968_init(void) -{ - int err = pnp_register_card_driver(&es968_pnpc_driver); - if (err) - return err; - - if (!es968_devices) { - pnp_unregister_card_driver(&es968_pnpc_driver); -#ifdef MODULE - snd_printk(KERN_ERR "no ES968 based soundcards found\n"); -#endif - return -ENODEV; - } - return 0; -} - -static void __exit alsa_card_es968_exit(void) -{ - pnp_unregister_card_driver(&es968_pnpc_driver); -} - -module_init(alsa_card_es968_init) -module_exit(alsa_card_es968_exit) -- cgit v1.2.3 From b0fb75ad5c8ca205396d7a493c9be5a5da802747 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2010 16:48:28 +0200 Subject: ALSA: es1688: add pedantic range checks Smatch complains that if (dev == SNDRV_CARDS) we're one past the end of the array. That's unlikely to happen in real life, I suppose. Also smatch complains about "strcpy(card->shortname, pcm->name);" The "pcm->name" buffer is 80 characters and "card->shortname" is 32 characters. If you follow the call paths it turns out we never actually use more than 16 characters so it's not a problem. But anyway, let's make it easy for people auditing this in the future. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/isa/es1688/es1688.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'sound/isa') diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index fdcce311f80a..0cde8131a575 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -149,10 +149,11 @@ static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n) if (error < 0) return error; - strcpy(card->driver, "ES1688"); - strcpy(card->shortname, pcm->name); - sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, - chip->port, chip->irq, chip->dma8); + strlcpy(card->driver, "ES1688", sizeof(card->driver)); + strlcpy(card->shortname, pcm->name, sizeof(card->shortname)); + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, + chip->irq, chip->dma8); if (fm_port[n] == SNDRV_AUTO_PORT) fm_port[n] = port[n]; /* share the same port */ @@ -271,6 +272,8 @@ static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard, if (enable[dev] && isapnp[dev]) break; } + if (dev == SNDRV_CARDS) + return -ENODEV; error = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_es1688), &card); -- cgit v1.2.3