diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/hwdep.c | 3 | ||||
-rw-r--r-- | sound/core/init.c | 92 | ||||
-rw-r--r-- | sound/isa/es18xx.c | 1 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 7 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0.c | 1 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 5 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2yaudio.c | 18 | ||||
-rw-r--r-- | sound/usb/usx2y/usx2yhwdeppcm.c | 17 |
11 files changed, 84 insertions, 69 deletions
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 9aa9d94891f0..46b47689362c 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -158,6 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) { int err = -ENXIO; struct snd_hwdep *hw = file->private_data; + struct module *mod = hw->card->module; mutex_lock(&hw->open_mutex); if (hw->ops.release) { err = hw->ops.release(hw, file); @@ -167,7 +168,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) hw->used--; snd_card_file_remove(hw->card, file); mutex_unlock(&hw->open_mutex); - module_put(hw->card->module); + module_put(mod); return err; } diff --git a/sound/core/init.c b/sound/core/init.c index d7607a25acdf..3058d626a90a 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -33,10 +33,10 @@ #include <sound/control.h> #include <sound/info.h> -struct snd_shutdown_f_ops { - struct file_operations f_ops; - struct snd_shutdown_f_ops *next; -}; +static DEFINE_SPINLOCK(shutdown_lock); +static LIST_HEAD(shutdown_files); + +static struct file_operations snd_shutdown_f_ops; static unsigned int snd_cards_lock; /* locked for registering/using */ struct snd_card *snd_cards[SNDRV_CARDS]; @@ -198,6 +198,25 @@ static ssize_t snd_disconnect_write(struct file *file, const char __user *buf, return -ENODEV; } +static int snd_disconnect_release(struct inode *inode, struct file *file) +{ + struct snd_monitor_file *df = NULL, *_df; + + spin_lock(&shutdown_lock); + list_for_each_entry(_df, &shutdown_files, shutdown_list) { + if (_df->file == file) { + df = _df; + break; + } + } + spin_unlock(&shutdown_lock); + + if (likely(df)) + return df->disconnected_f_op->release(inode, file); + + panic("%s(%p, %p) failed!", __FUNCTION__, inode, file); +} + static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) { return POLLERR | POLLNVAL; @@ -219,6 +238,22 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on) return -ENODEV; } +static struct file_operations snd_shutdown_f_ops = +{ + .owner = THIS_MODULE, + .llseek = snd_disconnect_llseek, + .read = snd_disconnect_read, + .write = snd_disconnect_write, + .release = snd_disconnect_release, + .poll = snd_disconnect_poll, + .unlocked_ioctl = snd_disconnect_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = snd_disconnect_ioctl, +#endif + .mmap = snd_disconnect_mmap, + .fasync = snd_disconnect_fasync +}; + /** * snd_card_disconnect - disconnect all APIs from the file-operations (user space) * @card: soundcard structure @@ -234,9 +269,6 @@ int snd_card_disconnect(struct snd_card *card) { struct snd_monitor_file *mfile; struct file *file; - struct snd_shutdown_f_ops *s_f_ops; - struct file_operations *f_ops; - const struct file_operations *old_f_ops; int err; spin_lock(&card->files_lock); @@ -261,34 +293,14 @@ int snd_card_disconnect(struct snd_card *card) /* it's critical part, use endless loop */ /* we have no room to fail */ - s_f_ops = kmalloc(sizeof(struct snd_shutdown_f_ops), GFP_ATOMIC); - if (s_f_ops == NULL) - panic("Atomic allocation failed for snd_shutdown_f_ops!"); - - f_ops = &s_f_ops->f_ops; - - memset(f_ops, 0, sizeof(*f_ops)); - f_ops->owner = file->f_op->owner; - f_ops->release = file->f_op->release; - f_ops->llseek = snd_disconnect_llseek; - f_ops->read = snd_disconnect_read; - f_ops->write = snd_disconnect_write; - f_ops->poll = snd_disconnect_poll; - f_ops->unlocked_ioctl = snd_disconnect_ioctl; -#ifdef CONFIG_COMPAT - f_ops->compat_ioctl = snd_disconnect_ioctl; -#endif - f_ops->mmap = snd_disconnect_mmap; - f_ops->fasync = snd_disconnect_fasync; + mfile->disconnected_f_op = mfile->file->f_op; - s_f_ops->next = card->s_f_ops; - card->s_f_ops = s_f_ops; - - f_ops = fops_get(f_ops); + spin_lock(&shutdown_lock); + list_add(&mfile->shutdown_list, &shutdown_files); + spin_unlock(&shutdown_lock); - old_f_ops = file->f_op; - file->f_op = f_ops; /* must be atomic */ - fops_put(old_f_ops); + fops_get(&snd_shutdown_f_ops); + mfile->file->f_op = &snd_shutdown_f_ops; mfile = mfile->next; } @@ -326,8 +338,6 @@ EXPORT_SYMBOL(snd_card_disconnect); */ static int snd_card_do_free(struct snd_card *card) { - struct snd_shutdown_f_ops *s_f_ops; - #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) if (snd_mixer_oss_notify_callback) snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE); @@ -351,11 +361,6 @@ static int snd_card_do_free(struct snd_card *card) snd_printk(KERN_WARNING "unable to free card info\n"); /* Not fatal error */ } - while (card->s_f_ops) { - s_f_ops = card->s_f_ops; - card->s_f_ops = s_f_ops->next; - kfree(s_f_ops); - } kfree(card); return 0; } @@ -670,6 +675,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) if (mfile == NULL) return -ENOMEM; mfile->file = file; + mfile->disconnected_f_op = NULL; mfile->next = NULL; spin_lock(&card->files_lock); if (card->shutdown) { @@ -716,6 +722,12 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) pfile = mfile; mfile = mfile->next; } + if (mfile && mfile->disconnected_f_op) { + fops_put(mfile->disconnected_f_op); + spin_lock(&shutdown_lock); + list_del(&mfile->shutdown_list); + spin_unlock(&shutdown_lock); + } if (card->files == NULL) last_close = 1; spin_unlock(&card->files_lock); diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 2398d2c55feb..725c115ff97d 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -2154,6 +2154,7 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, } /* Control port initialization */ if (pnp_activate_dev(acard->devc) < 0) { + kfree(cfg); snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); return -EAGAIN; } diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index dc28b111a06d..15be6ba87c82 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -530,7 +530,7 @@ AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), -AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), +AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0), AC97_ENUM("Out3 Mux", wm9711_enum[2]), AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), @@ -575,13 +575,14 @@ AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), -AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), +AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), AC97_ENUM("Mic Select Source", wm9711_enum[7]), -AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), +AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), +AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index ef189d7f09d3..6ed5ad59f5b5 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -128,6 +128,7 @@ static int snd_vortex_dev_free(struct snd_device *device) // Take down PCI interface. synchronize_irq(vortex->irq); free_irq(vortex->irq, vortex); + iounmap(vortex->mmio); pci_release_regions(vortex->pci_dev); pci_disable_device(vortex->pci_dev); kfree(vortex); diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index be65d4db8e27..8058059c56e9 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1461,8 +1461,8 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) /* resore for spdif */ if (emu->audigy) - outl(emu->port + A_IOCFG, emu->saved_a_iocfg); - outl(emu->port + HCFG, emu->saved_hcfg); + outl(emu->saved_a_iocfg, emu->port + A_IOCFG); + outl(emu->saved_hcfg, emu->port + HCFG); val = emu->saved_ptr; for (reg = saved_regs; *reg != 0xff; reg++) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a76a778d0a1f..feeed12920b4 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1682,6 +1682,7 @@ static struct pci_device_id azx_ids[] = { { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */ { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */ + { 0x10de, 0x03f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 03f0 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d08d2e399c8f..84a3eb8aacc2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5076,6 +5076,10 @@ static struct hda_board_config alc883_cfg_tbl[] = { { .modelname = "acer", .config = ALC883_ACER }, { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102, + .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f, + .config = ALC883_ACER }, { .modelname = "auto", .config = ALC883_AUTO }, {} }; diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 76ec3d75fa9e..cc87dff1eb56 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -297,8 +297,13 @@ static int patch_si3054(struct hda_codec *codec) struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x11c11040, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, {} }; diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index e662281a751a..367f8a32a665 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -322,7 +322,7 @@ static void i_usX2Y_urb_complete(struct urb *urb) usX2Y_error_urb_status(usX2Y, subs, urb); return; } - if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) + if (likely(urb->start_frame == usX2Y->wait_iso_frame)) subs->completed_urb = urb; else { usX2Y_error_sequence(usX2Y, subs, urb); @@ -335,13 +335,9 @@ static void i_usX2Y_urb_complete(struct urb *urb) atomic_read(&capsubs->state) >= state_PREPARED && (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { - if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) { - if (nr_of_packs() <= urb->start_frame && - urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci - usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs(); - else - usX2Y->wait_iso_frame += nr_of_packs(); - } else { + if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) + usX2Y->wait_iso_frame += nr_of_packs(); + else { snd_printdd("\n"); usX2Y_clients_stop(usX2Y); } @@ -495,7 +491,6 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs) if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) goto start; } - usX2Y->wait_iso_frame = -1; start: usX2Y_subs_startup(subs); @@ -516,10 +511,9 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs) snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); err = -EPIPE; goto cleanup; - } else { - if (0 > usX2Y->wait_iso_frame) + } else + if (i == 0) usX2Y->wait_iso_frame = urb->start_frame; - } urb->transfer_flags = 0; } else { atomic_set(&subs->state, state_STARTING1); diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 9acef9d90543..8f3e35e24e72 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -243,7 +243,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) usX2Y_error_urb_status(usX2Y, subs, urb); return; } - if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) + if (likely(urb->start_frame == usX2Y->wait_iso_frame)) subs->completed_urb = urb; else { usX2Y_error_sequence(usX2Y, subs, urb); @@ -256,13 +256,9 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED && (NULL == capsubs2 || capsubs2->completed_urb) && (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { - if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) { - if (nr_of_packs() <= urb->start_frame && - urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci - usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs(); - else - usX2Y->wait_iso_frame += nr_of_packs(); - } else { + if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) + usX2Y->wait_iso_frame += nr_of_packs(); + else { snd_printdd("\n"); usX2Y_clients_stop(usX2Y); } @@ -433,7 +429,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs) if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) goto start; } - usX2Y->wait_iso_frame = -1; start: usX2Y_usbpcm_subs_startup(subs); @@ -459,7 +454,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs) goto cleanup; } else { snd_printdd("%i\n", urb->start_frame); - if (0 > usX2Y->wait_iso_frame) + if (u == 0) usX2Y->wait_iso_frame = urb->start_frame; } urb->transfer_flags = 0; @@ -632,7 +627,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card) for (s = 0; s < 2; ++s) { struct snd_pcm_substream *substream; substream = pcm->streams[s].substream; - if (SUBSTREAM_BUSY(substream)) + if (substream && SUBSTREAM_BUSY(substream)) err = -EBUSY; } } |