aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-06 14:35:08 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-06 14:35:08 -0400
commit20ebba65093e7bbae1421f071cffed436048e700 (patch)
treec3dfc619b4db65e732859f5490a51df7d20960eb
parent815a965b0e6d925646e1f6012175830ef21e0d21 (diff)
parent5a078351d2d0a7ae834087de3637eb42cfd209e3 (diff)
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: [ALSA] version 1.0.13 [ALSA] sound/pci/au88x0/au88x0.c: ioremap balanced with iounmap [ALSA] Handle file operations during snd_card disconnects using static file->f_op [ALSA] emu10k1: Fix outl() in snd_emu10k1_resume_regs() [ALSA] Repair snd-usb-usx2y for usb 2.6.18 [ALSA] Fix bug in snd-usb-usx2y's usX2Y_pcms_lock_check() [ALSA] Dereference after free in snd_hwdep_release() [ALSA] Fix memory leak in sound/isa/es18xx.c [ALSA] hda-intel - New pci id for Nvidia MCP61 [ALSA] Add new subdevice ids for hda-intel [ALSA] WM9712 fixes for ac97_patch.c [ALSA] hda/patch_si3054: new codec vendor IDs
-rw-r--r--include/sound/core.h4
-rw-r--r--include/sound/version.h6
-rw-r--r--sound/core/hwdep.c3
-rw-r--r--sound/core/init.c92
-rw-r--r--sound/isa/es18xx.c1
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/au88x0/au88x0.c1
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c4
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_realtek.c4
-rw-r--r--sound/pci/hda/patch_si3054.c5
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c18
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c17
13 files changed, 89 insertions, 74 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index b056ea925ecf..fa1ca0127bab 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -89,10 +89,10 @@ struct snd_device {
89struct snd_monitor_file { 89struct snd_monitor_file {
90 struct file *file; 90 struct file *file;
91 struct snd_monitor_file *next; 91 struct snd_monitor_file *next;
92 const struct file_operations *disconnected_f_op;
93 struct list_head shutdown_list;
92}; 94};
93 95
94struct snd_shutdown_f_ops; /* define it later in init.c */
95
96/* main structure for soundcard */ 96/* main structure for soundcard */
97 97
98struct snd_card { 98struct snd_card {
diff --git a/include/sound/version.h b/include/sound/version.h
index 2ee849d0e198..4ad86eb6440b 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h. Generated by configure. */ 1/* include/version.h. Generated by alsa/ksync script. */
2#define CONFIG_SND_VERSION "1.0.12rc1" 2#define CONFIG_SND_VERSION "1.0.13"
3#define CONFIG_SND_DATE " (Thu Jun 22 13:55:50 2006 UTC)" 3#define CONFIG_SND_DATE " (Fri Oct 06 18:28:19 2006 UTC)"
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)
158{ 158{
159 int err = -ENXIO; 159 int err = -ENXIO;
160 struct snd_hwdep *hw = file->private_data; 160 struct snd_hwdep *hw = file->private_data;
161 struct module *mod = hw->card->module;
161 mutex_lock(&hw->open_mutex); 162 mutex_lock(&hw->open_mutex);
162 if (hw->ops.release) { 163 if (hw->ops.release) {
163 err = hw->ops.release(hw, file); 164 err = hw->ops.release(hw, file);
@@ -167,7 +168,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
167 hw->used--; 168 hw->used--;
168 snd_card_file_remove(hw->card, file); 169 snd_card_file_remove(hw->card, file);
169 mutex_unlock(&hw->open_mutex); 170 mutex_unlock(&hw->open_mutex);
170 module_put(hw->card->module); 171 module_put(mod);
171 return err; 172 return err;
172} 173}
173 174
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 @@
33#include <sound/control.h> 33#include <sound/control.h>
34#include <sound/info.h> 34#include <sound/info.h>
35 35
36struct snd_shutdown_f_ops { 36static DEFINE_SPINLOCK(shutdown_lock);
37 struct file_operations f_ops; 37static LIST_HEAD(shutdown_files);
38 struct snd_shutdown_f_ops *next; 38
39}; 39static struct file_operations snd_shutdown_f_ops;
40 40
41static unsigned int snd_cards_lock; /* locked for registering/using */ 41static unsigned int snd_cards_lock; /* locked for registering/using */
42struct snd_card *snd_cards[SNDRV_CARDS]; 42struct snd_card *snd_cards[SNDRV_CARDS];
@@ -198,6 +198,25 @@ static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
198 return -ENODEV; 198 return -ENODEV;
199} 199}
200 200
201static int snd_disconnect_release(struct inode *inode, struct file *file)
202{
203 struct snd_monitor_file *df = NULL, *_df;
204
205 spin_lock(&shutdown_lock);
206 list_for_each_entry(_df, &shutdown_files, shutdown_list) {
207 if (_df->file == file) {
208 df = _df;
209 break;
210 }
211 }
212 spin_unlock(&shutdown_lock);
213
214 if (likely(df))
215 return df->disconnected_f_op->release(inode, file);
216
217 panic("%s(%p, %p) failed!", __FUNCTION__, inode, file);
218}
219
201static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) 220static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
202{ 221{
203 return POLLERR | POLLNVAL; 222 return POLLERR | POLLNVAL;
@@ -219,6 +238,22 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on)
219 return -ENODEV; 238 return -ENODEV;
220} 239}
221 240
241static struct file_operations snd_shutdown_f_ops =
242{
243 .owner = THIS_MODULE,
244 .llseek = snd_disconnect_llseek,
245 .read = snd_disconnect_read,
246 .write = snd_disconnect_write,
247 .release = snd_disconnect_release,
248 .poll = snd_disconnect_poll,
249 .unlocked_ioctl = snd_disconnect_ioctl,
250#ifdef CONFIG_COMPAT
251 .compat_ioctl = snd_disconnect_ioctl,
252#endif
253 .mmap = snd_disconnect_mmap,
254 .fasync = snd_disconnect_fasync
255};
256
222/** 257/**
223 * snd_card_disconnect - disconnect all APIs from the file-operations (user space) 258 * snd_card_disconnect - disconnect all APIs from the file-operations (user space)
224 * @card: soundcard structure 259 * @card: soundcard structure
@@ -234,9 +269,6 @@ int snd_card_disconnect(struct snd_card *card)
234{ 269{
235 struct snd_monitor_file *mfile; 270 struct snd_monitor_file *mfile;
236 struct file *file; 271 struct file *file;
237 struct snd_shutdown_f_ops *s_f_ops;
238 struct file_operations *f_ops;
239 const struct file_operations *old_f_ops;
240 int err; 272 int err;
241 273
242 spin_lock(&card->files_lock); 274 spin_lock(&card->files_lock);
@@ -261,34 +293,14 @@ int snd_card_disconnect(struct snd_card *card)
261 293
262 /* it's critical part, use endless loop */ 294 /* it's critical part, use endless loop */
263 /* we have no room to fail */ 295 /* we have no room to fail */
264 s_f_ops = kmalloc(sizeof(struct snd_shutdown_f_ops), GFP_ATOMIC); 296 mfile->disconnected_f_op = mfile->file->f_op;
265 if (s_f_ops == NULL)
266 panic("Atomic allocation failed for snd_shutdown_f_ops!");
267
268 f_ops = &s_f_ops->f_ops;
269
270 memset(f_ops, 0, sizeof(*f_ops));
271 f_ops->owner = file->f_op->owner;
272 f_ops->release = file->f_op->release;
273 f_ops->llseek = snd_disconnect_llseek;
274 f_ops->read = snd_disconnect_read;
275 f_ops->write = snd_disconnect_write;
276 f_ops->poll = snd_disconnect_poll;
277 f_ops->unlocked_ioctl = snd_disconnect_ioctl;
278#ifdef CONFIG_COMPAT
279 f_ops->compat_ioctl = snd_disconnect_ioctl;
280#endif
281 f_ops->mmap = snd_disconnect_mmap;
282 f_ops->fasync = snd_disconnect_fasync;
283 297
284 s_f_ops->next = card->s_f_ops; 298 spin_lock(&shutdown_lock);
285 card->s_f_ops = s_f_ops; 299 list_add(&mfile->shutdown_list, &shutdown_files);
286 300 spin_unlock(&shutdown_lock);
287 f_ops = fops_get(f_ops);
288 301
289 old_f_ops = file->f_op; 302 fops_get(&snd_shutdown_f_ops);
290 file->f_op = f_ops; /* must be atomic */ 303 mfile->file->f_op = &snd_shutdown_f_ops;
291 fops_put(old_f_ops);
292 304
293 mfile = mfile->next; 305 mfile = mfile->next;
294 } 306 }
@@ -326,8 +338,6 @@ EXPORT_SYMBOL(snd_card_disconnect);
326 */ 338 */
327static int snd_card_do_free(struct snd_card *card) 339static int snd_card_do_free(struct snd_card *card)
328{ 340{
329 struct snd_shutdown_f_ops *s_f_ops;
330
331#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 341#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
332 if (snd_mixer_oss_notify_callback) 342 if (snd_mixer_oss_notify_callback)
333 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE); 343 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)
351 snd_printk(KERN_WARNING "unable to free card info\n"); 361 snd_printk(KERN_WARNING "unable to free card info\n");
352 /* Not fatal error */ 362 /* Not fatal error */
353 } 363 }
354 while (card->s_f_ops) {
355 s_f_ops = card->s_f_ops;
356 card->s_f_ops = s_f_ops->next;
357 kfree(s_f_ops);
358 }
359 kfree(card); 364 kfree(card);
360 return 0; 365 return 0;
361} 366}
@@ -670,6 +675,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
670 if (mfile == NULL) 675 if (mfile == NULL)
671 return -ENOMEM; 676 return -ENOMEM;
672 mfile->file = file; 677 mfile->file = file;
678 mfile->disconnected_f_op = NULL;
673 mfile->next = NULL; 679 mfile->next = NULL;
674 spin_lock(&card->files_lock); 680 spin_lock(&card->files_lock);
675 if (card->shutdown) { 681 if (card->shutdown) {
@@ -716,6 +722,12 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
716 pfile = mfile; 722 pfile = mfile;
717 mfile = mfile->next; 723 mfile = mfile->next;
718 } 724 }
725 if (mfile && mfile->disconnected_f_op) {
726 fops_put(mfile->disconnected_f_op);
727 spin_lock(&shutdown_lock);
728 list_del(&mfile->shutdown_list);
729 spin_unlock(&shutdown_lock);
730 }
719 if (card->files == NULL) 731 if (card->files == NULL)
720 last_close = 1; 732 last_close = 1;
721 spin_unlock(&card->files_lock); 733 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,
2154 } 2154 }
2155 /* Control port initialization */ 2155 /* Control port initialization */
2156 if (pnp_activate_dev(acard->devc) < 0) { 2156 if (pnp_activate_dev(acard->devc) < 0) {
2157 kfree(cfg);
2157 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); 2158 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
2158 return -EAGAIN; 2159 return -EAGAIN;
2159 } 2160 }
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]),
530AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), 530AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
531 531
532AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), 532AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
533AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), 533AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
534AC97_ENUM("Out3 Mux", wm9711_enum[2]), 534AC97_ENUM("Out3 Mux", wm9711_enum[2]),
535AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), 535AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
536AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), 536AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
@@ -575,13 +575,14 @@ AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
575 575
576AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), 576AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
577AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), 577AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
578AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), 578AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
579AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 579AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
580 580
581AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), 581AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
582AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), 582AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
583AC97_ENUM("Mic Select Source", wm9711_enum[7]), 583AC97_ENUM("Mic Select Source", wm9711_enum[7]),
584AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), 584AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
585AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
585AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 586AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
586 587
587AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), 588AC97_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)
128 // Take down PCI interface. 128 // Take down PCI interface.
129 synchronize_irq(vortex->irq); 129 synchronize_irq(vortex->irq);
130 free_irq(vortex->irq, vortex); 130 free_irq(vortex->irq, vortex);
131 iounmap(vortex->mmio);
131 pci_release_regions(vortex->pci_dev); 132 pci_release_regions(vortex->pci_dev);
132 pci_disable_device(vortex->pci_dev); 133 pci_disable_device(vortex->pci_dev);
133 kfree(vortex); 134 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)
1461 1461
1462 /* resore for spdif */ 1462 /* resore for spdif */
1463 if (emu->audigy) 1463 if (emu->audigy)
1464 outl(emu->port + A_IOCFG, emu->saved_a_iocfg); 1464 outl(emu->saved_a_iocfg, emu->port + A_IOCFG);
1465 outl(emu->port + HCFG, emu->saved_hcfg); 1465 outl(emu->saved_hcfg, emu->port + HCFG);
1466 1466
1467 val = emu->saved_ptr; 1467 val = emu->saved_ptr;
1468 for (reg = saved_regs; *reg != 0xff; reg++) 1468 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[] = {
1682 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ 1682 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
1683 { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */ 1683 { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
1684 { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */ 1684 { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
1685 { 0x10de, 0x03f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 03f0 */
1685 { 0, } 1686 { 0, }
1686}; 1687};
1687MODULE_DEVICE_TABLE(pci, azx_ids); 1688MODULE_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[] = {
5076 { .modelname = "acer", .config = ALC883_ACER }, 5076 { .modelname = "acer", .config = ALC883_ACER },
5077 { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, 5077 { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
5078 .config = ALC883_ACER }, 5078 .config = ALC883_ACER },
5079 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102,
5080 .config = ALC883_ACER },
5081 { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
5082 .config = ALC883_ACER },
5079 { .modelname = "auto", .config = ALC883_AUTO }, 5083 { .modelname = "auto", .config = ALC883_AUTO },
5080 {} 5084 {}
5081}; 5085};
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)
297struct hda_codec_preset snd_hda_preset_si3054[] = { 297struct hda_codec_preset snd_hda_preset_si3054[] = {
298 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 298 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
299 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 299 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
300 { .id = 0x11c11040, .name = "Si3054", .patch = patch_si3054 },
300 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 301 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
302 { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 },
303 { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 },
304 { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
301 { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, 305 { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
306 { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
302 {} 307 {}
303}; 308};
304 309
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)
322 usX2Y_error_urb_status(usX2Y, subs, urb); 322 usX2Y_error_urb_status(usX2Y, subs, urb);
323 return; 323 return;
324 } 324 }
325 if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) 325 if (likely(urb->start_frame == usX2Y->wait_iso_frame))
326 subs->completed_urb = urb; 326 subs->completed_urb = urb;
327 else { 327 else {
328 usX2Y_error_sequence(usX2Y, subs, urb); 328 usX2Y_error_sequence(usX2Y, subs, urb);
@@ -335,13 +335,9 @@ static void i_usX2Y_urb_complete(struct urb *urb)
335 atomic_read(&capsubs->state) >= state_PREPARED && 335 atomic_read(&capsubs->state) >= state_PREPARED &&
336 (playbacksubs->completed_urb || 336 (playbacksubs->completed_urb ||
337 atomic_read(&playbacksubs->state) < state_PREPARED)) { 337 atomic_read(&playbacksubs->state) < state_PREPARED)) {
338 if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) { 338 if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
339 if (nr_of_packs() <= urb->start_frame && 339 usX2Y->wait_iso_frame += nr_of_packs();
340 urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci 340 else {
341 usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
342 else
343 usX2Y->wait_iso_frame += nr_of_packs();
344 } else {
345 snd_printdd("\n"); 341 snd_printdd("\n");
346 usX2Y_clients_stop(usX2Y); 342 usX2Y_clients_stop(usX2Y);
347 } 343 }
@@ -495,7 +491,6 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
495 if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) 491 if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
496 goto start; 492 goto start;
497 } 493 }
498 usX2Y->wait_iso_frame = -1;
499 494
500 start: 495 start:
501 usX2Y_subs_startup(subs); 496 usX2Y_subs_startup(subs);
@@ -516,10 +511,9 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
516 snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); 511 snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
517 err = -EPIPE; 512 err = -EPIPE;
518 goto cleanup; 513 goto cleanup;
519 } else { 514 } else
520 if (0 > usX2Y->wait_iso_frame) 515 if (i == 0)
521 usX2Y->wait_iso_frame = urb->start_frame; 516 usX2Y->wait_iso_frame = urb->start_frame;
522 }
523 urb->transfer_flags = 0; 517 urb->transfer_flags = 0;
524 } else { 518 } else {
525 atomic_set(&subs->state, state_STARTING1); 519 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)
243 usX2Y_error_urb_status(usX2Y, subs, urb); 243 usX2Y_error_urb_status(usX2Y, subs, urb);
244 return; 244 return;
245 } 245 }
246 if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) 246 if (likely(urb->start_frame == usX2Y->wait_iso_frame))
247 subs->completed_urb = urb; 247 subs->completed_urb = urb;
248 else { 248 else {
249 usX2Y_error_sequence(usX2Y, subs, urb); 249 usX2Y_error_sequence(usX2Y, subs, urb);
@@ -256,13 +256,9 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
256 if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED && 256 if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
257 (NULL == capsubs2 || capsubs2->completed_urb) && 257 (NULL == capsubs2 || capsubs2->completed_urb) &&
258 (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { 258 (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
259 if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) { 259 if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
260 if (nr_of_packs() <= urb->start_frame && 260 usX2Y->wait_iso_frame += nr_of_packs();
261 urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci 261 else {
262 usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
263 else
264 usX2Y->wait_iso_frame += nr_of_packs();
265 } else {
266 snd_printdd("\n"); 262 snd_printdd("\n");
267 usX2Y_clients_stop(usX2Y); 263 usX2Y_clients_stop(usX2Y);
268 } 264 }
@@ -433,7 +429,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
433 if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) 429 if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
434 goto start; 430 goto start;
435 } 431 }
436 usX2Y->wait_iso_frame = -1;
437 432
438 start: 433 start:
439 usX2Y_usbpcm_subs_startup(subs); 434 usX2Y_usbpcm_subs_startup(subs);
@@ -459,7 +454,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
459 goto cleanup; 454 goto cleanup;
460 } else { 455 } else {
461 snd_printdd("%i\n", urb->start_frame); 456 snd_printdd("%i\n", urb->start_frame);
462 if (0 > usX2Y->wait_iso_frame) 457 if (u == 0)
463 usX2Y->wait_iso_frame = urb->start_frame; 458 usX2Y->wait_iso_frame = urb->start_frame;
464 } 459 }
465 urb->transfer_flags = 0; 460 urb->transfer_flags = 0;
@@ -632,7 +627,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
632 for (s = 0; s < 2; ++s) { 627 for (s = 0; s < 2; ++s) {
633 struct snd_pcm_substream *substream; 628 struct snd_pcm_substream *substream;
634 substream = pcm->streams[s].substream; 629 substream = pcm->streams[s].substream;
635 if (SUBSTREAM_BUSY(substream)) 630 if (substream && SUBSTREAM_BUSY(substream))
636 err = -EBUSY; 631 err = -EBUSY;
637 } 632 }
638 } 633 }