提交 bd27e6d3 编写于 作者: L Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: Fix vunmap and free order in snd_free_sgbuf_pages()
  ALSA: mixart, fix lock imbalance
  ALSA: pcm_oss, fix locking typo
  ALSA: oss-mixer - Fixes recording gain control
  ALSA: hda - Workaround for buggy DMA position on ATI controllers
  ALSA: hda - Fix DMA mask for ATI controllers
  ALSA: opl3sa2 - Fix NULL dereference when suspending snd_opl3sa2
...@@ -692,6 +692,9 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer, ...@@ -692,6 +692,9 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) {
snd_mixer_oss_put_volume1_vol(fmixer, pslot,
slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) { } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right); snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) { } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {
......
...@@ -2872,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -2872,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
setup = kmalloc(sizeof(*setup), GFP_KERNEL); setup = kmalloc(sizeof(*setup), GFP_KERNEL);
if (! setup) { if (! setup) {
buffer->error = -ENOMEM; buffer->error = -ENOMEM;
mutex_lock(&pstr->oss.setup_mutex); mutex_unlock(&pstr->oss.setup_mutex);
return; return;
} }
if (pstr->oss.setup_list == NULL) if (pstr->oss.setup_list == NULL)
...@@ -2886,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -2886,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
if (! template.task_name) { if (! template.task_name) {
kfree(setup); kfree(setup);
buffer->error = -ENOMEM; buffer->error = -ENOMEM;
mutex_lock(&pstr->oss.setup_mutex); mutex_unlock(&pstr->oss.setup_mutex);
return; return;
} }
} }
......
...@@ -38,6 +38,10 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) ...@@ -38,6 +38,10 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
if (! sgbuf) if (! sgbuf)
return -EINVAL; return -EINVAL;
if (dmab->area)
vunmap(dmab->area);
dmab->area = NULL;
tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
tmpb.dev.dev = sgbuf->dev; tmpb.dev.dev = sgbuf->dev;
for (i = 0; i < sgbuf->pages; i++) { for (i = 0; i < sgbuf->pages; i++) {
...@@ -48,9 +52,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) ...@@ -48,9 +52,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
snd_dma_free_pages(&tmpb); snd_dma_free_pages(&tmpb);
} }
if (dmab->area)
vunmap(dmab->area);
dmab->area = NULL;
kfree(sgbuf->table); kfree(sgbuf->table);
kfree(sgbuf->page_table); kfree(sgbuf->page_table);
......
...@@ -550,21 +550,27 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card) ...@@ -550,21 +550,27 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
{ {
if (card) {
struct snd_opl3sa2 *chip = card->private_data; struct snd_opl3sa2 *chip = card->private_data;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
chip->wss->suspend(chip->wss); chip->wss->suspend(chip->wss);
/* power down */ /* power down */
snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
}
return 0; return 0;
} }
static int snd_opl3sa2_resume(struct snd_card *card) static int snd_opl3sa2_resume(struct snd_card *card)
{ {
struct snd_opl3sa2 *chip = card->private_data; struct snd_opl3sa2 *chip;
int i; int i;
if (!card)
return 0;
chip = card->private_data;
/* power up */ /* power up */
snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0);
......
...@@ -2059,16 +2059,22 @@ static int __devinit check_position_fix(struct azx *chip, int fix) ...@@ -2059,16 +2059,22 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
{ {
const struct snd_pci_quirk *q; const struct snd_pci_quirk *q;
/* Check VIA HD Audio Controller exist */ switch (fix) {
if (chip->pci->vendor == PCI_VENDOR_ID_VIA && case POS_FIX_LPIB:
chip->pci->device == VIA_HDAC_DEVICE_ID) { case POS_FIX_POSBUF:
return fix;
}
/* Check VIA/ATI HD Audio Controller exist */
switch (chip->driver_type) {
case AZX_DRIVER_VIA:
case AZX_DRIVER_ATI:
chip->via_dmapos_patch = 1; chip->via_dmapos_patch = 1;
/* Use link position directly, avoid any transfer problem. */ /* Use link position directly, avoid any transfer problem. */
return POS_FIX_LPIB; return POS_FIX_LPIB;
} }
chip->via_dmapos_patch = 0; chip->via_dmapos_patch = 0;
if (fix == POS_FIX_AUTO) {
q = snd_pci_quirk_lookup(chip->pci, position_fix_list); q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
if (q) { if (q) {
printk(KERN_INFO printk(KERN_INFO
...@@ -2077,8 +2083,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix) ...@@ -2077,8 +2083,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
q->value, q->subvendor, q->subdevice); q->value, q->subvendor, q->subdevice);
return q->value; return q->value;
} }
} return POS_FIX_AUTO;
return fix;
} }
/* /*
...@@ -2210,9 +2215,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -2210,9 +2215,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
gcap = azx_readw(chip, GCAP); gcap = azx_readw(chip, GCAP);
snd_printdd("chipset global capabilities = 0x%x\n", gcap); snd_printdd("chipset global capabilities = 0x%x\n", gcap);
/* ATI chips seems buggy about 64bit DMA addresses */
if (chip->driver_type == AZX_DRIVER_ATI)
gcap &= ~0x01;
/* allow 64bit DMA address if supported by H/W */ /* allow 64bit DMA address if supported by H/W */
if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
else {
pci_set_dma_mask(pci, DMA_32BIT_MASK);
pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
}
/* read number of streams from GCAP register instead of using /* read number of streams from GCAP register instead of using
* hardcoded value * hardcoded value
......
...@@ -607,6 +607,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, ...@@ -607,6 +607,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
/* set the format to the board */ /* set the format to the board */
err = mixart_set_format(stream, format); err = mixart_set_format(stream, format);
if(err < 0) { if(err < 0) {
mutex_unlock(&mgr->setup_mutex);
return err; return err;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册