aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usx2y
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usx2y')
-rw-r--r--sound/usb/usx2y/us122l.c11
-rw-r--r--sound/usb/usx2y/usbusx2y.c13
-rw-r--r--sound/usb/usx2y/usbusx2y.h2
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c60
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c76
5 files changed, 73 insertions, 89 deletions
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 999550bbad40..cf5dc33f4a6d 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -535,7 +535,9 @@ static void snd_us122l_free(struct snd_card *card)
535 snd_us122l_card_used[index] = 0; 535 snd_us122l_card_used[index] = 0;
536} 536}
537 537
538static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) 538static int usx2y_create_card(struct usb_device *device,
539 struct usb_interface *intf,
540 struct snd_card **cardp)
539{ 541{
540 int dev; 542 int dev;
541 struct snd_card *card; 543 struct snd_card *card;
@@ -546,8 +548,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
546 break; 548 break;
547 if (dev >= SNDRV_CARDS) 549 if (dev >= SNDRV_CARDS)
548 return -ENODEV; 550 return -ENODEV;
549 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 551 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
550 sizeof(struct us122l), &card); 552 sizeof(struct us122l), &card);
551 if (err < 0) 553 if (err < 0)
552 return err; 554 return err;
553 snd_us122l_card_used[US122L(card)->card_index = dev] = 1; 555 snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
@@ -578,11 +580,10 @@ static int us122l_usb_probe(struct usb_interface *intf,
578 struct snd_card *card; 580 struct snd_card *card;
579 int err; 581 int err;
580 582
581 err = usx2y_create_card(device, &card); 583 err = usx2y_create_card(device, intf, &card);
582 if (err < 0) 584 if (err < 0)
583 return err; 585 return err;
584 586
585 snd_card_set_dev(card, &intf->dev);
586 if (!us122l_create_card(card)) { 587 if (!us122l_create_card(card)) {
587 snd_card_free(card); 588 snd_card_free(card);
588 return -EINVAL; 589 return -EINVAL;
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 5a51b18c50fe..91e0e2a4808c 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -332,7 +332,9 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = {
332 { /* terminator */ } 332 { /* terminator */ }
333}; 333};
334 334
335static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) 335static int usX2Y_create_card(struct usb_device *device,
336 struct usb_interface *intf,
337 struct snd_card **cardp)
336{ 338{
337 int dev; 339 int dev;
338 struct snd_card * card; 340 struct snd_card * card;
@@ -343,15 +345,15 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
343 break; 345 break;
344 if (dev >= SNDRV_CARDS) 346 if (dev >= SNDRV_CARDS)
345 return -ENODEV; 347 return -ENODEV;
346 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 348 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
347 sizeof(struct usX2Ydev), &card); 349 sizeof(struct usX2Ydev), &card);
348 if (err < 0) 350 if (err < 0)
349 return err; 351 return err;
350 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; 352 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
351 card->private_free = snd_usX2Y_card_private_free; 353 card->private_free = snd_usX2Y_card_private_free;
352 usX2Y(card)->dev = device; 354 usX2Y(card)->dev = device;
353 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 355 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
354 mutex_init(&usX2Y(card)->prepare_mutex); 356 mutex_init(&usX2Y(card)->pcm_mutex);
355 INIT_LIST_HEAD(&usX2Y(card)->midi_list); 357 INIT_LIST_HEAD(&usX2Y(card)->midi_list);
356 strcpy(card->driver, "USB "NAME_ALLCAPS""); 358 strcpy(card->driver, "USB "NAME_ALLCAPS"");
357 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 359 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
@@ -382,10 +384,9 @@ static int usX2Y_usb_probe(struct usb_device *device,
382 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) 384 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
383 return -EINVAL; 385 return -EINVAL;
384 386
385 err = usX2Y_create_card(device, &card); 387 err = usX2Y_create_card(device, intf, &card);
386 if (err < 0) 388 if (err < 0)
387 return err; 389 return err;
388 snd_card_set_dev(card, &intf->dev);
389 if ((err = usX2Y_hwdep_new(card, device)) < 0 || 390 if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
390 (err = snd_card_register(card)) < 0) { 391 (err = snd_card_register(card)) < 0) {
391 snd_card_free(card); 392 snd_card_free(card);
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index e43c0a86441a..6ae6b0806938 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -36,7 +36,7 @@ struct usX2Ydev {
36 unsigned int rate, 36 unsigned int rate,
37 format; 37 format;
38 int chip_status; 38 int chip_status;
39 struct mutex prepare_mutex; 39 struct mutex pcm_mutex;
40 struct us428ctls_sharedmem *us428ctls_sharedmem; 40 struct us428ctls_sharedmem *us428ctls_sharedmem;
41 int wait_iso_frame; 41 int wait_iso_frame;
42 wait_queue_head_t us428ctls_wait_queue_head; 42 wait_queue_head_t us428ctls_wait_queue_head;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6234a51625b1..a63330dd1407 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -752,36 +752,44 @@ static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
752 unsigned int rate = params_rate(hw_params); 752 unsigned int rate = params_rate(hw_params);
753 snd_pcm_format_t format = params_format(hw_params); 753 snd_pcm_format_t format = params_format(hw_params);
754 struct snd_card *card = substream->pstr->pcm->card; 754 struct snd_card *card = substream->pstr->pcm->card;
755 struct list_head *list; 755 struct usX2Ydev *dev = usX2Y(card);
756 int i;
756 757
758 mutex_lock(&usX2Y(card)->pcm_mutex);
757 snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params); 759 snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
758 // all pcm substreams off one usX2Y have to operate at the same rate & format 760 /* all pcm substreams off one usX2Y have to operate at the same
759 list_for_each(list, &card->devices) { 761 * rate & format
760 struct snd_device *dev; 762 */
761 struct snd_pcm *pcm; 763 for (i = 0; i < dev->pcm_devs * 2; i++) {
762 int s; 764 struct snd_usX2Y_substream *subs = dev->subs[i];
763 dev = snd_device(list); 765 struct snd_pcm_substream *test_substream;
764 if (dev->type != SNDRV_DEV_PCM) 766
767 if (!subs)
768 continue;
769 test_substream = subs->pcm_substream;
770 if (!test_substream || test_substream == substream ||
771 !test_substream->runtime)
765 continue; 772 continue;
766 pcm = dev->device_data; 773 if ((test_substream->runtime->format &&
767 for (s = 0; s < 2; ++s) { 774 test_substream->runtime->format != format) ||
768 struct snd_pcm_substream *test_substream; 775 (test_substream->runtime->rate &&
769 test_substream = pcm->streams[s].substream; 776 test_substream->runtime->rate != rate)) {
770 if (test_substream && test_substream != substream && 777 err = -EINVAL;
771 test_substream->runtime && 778 goto error;
772 ((test_substream->runtime->format &&
773 test_substream->runtime->format != format) ||
774 (test_substream->runtime->rate &&
775 test_substream->runtime->rate != rate)))
776 return -EINVAL;
777 } 779 }
778 } 780 }
779 if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) { 781
782 err = snd_pcm_lib_malloc_pages(substream,
783 params_buffer_bytes(hw_params));
784 if (err < 0) {
780 snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", 785 snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
781 substream, params_buffer_bytes(hw_params), err); 786 substream, params_buffer_bytes(hw_params), err);
782 return err; 787 goto error;
783 } 788 }
784 return 0; 789
790 error:
791 mutex_unlock(&usX2Y(card)->pcm_mutex);
792 return err;
785} 793}
786 794
787/* 795/*
@@ -791,7 +799,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
791{ 799{
792 struct snd_pcm_runtime *runtime = substream->runtime; 800 struct snd_pcm_runtime *runtime = substream->runtime;
793 struct snd_usX2Y_substream *subs = runtime->private_data; 801 struct snd_usX2Y_substream *subs = runtime->private_data;
794 mutex_lock(&subs->usX2Y->prepare_mutex); 802 mutex_lock(&subs->usX2Y->pcm_mutex);
795 snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); 803 snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
796 804
797 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 805 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -812,7 +820,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
812 usX2Y_urbs_release(subs); 820 usX2Y_urbs_release(subs);
813 } 821 }
814 } 822 }
815 mutex_unlock(&subs->usX2Y->prepare_mutex); 823 mutex_unlock(&subs->usX2Y->pcm_mutex);
816 return snd_pcm_lib_free_pages(substream); 824 return snd_pcm_lib_free_pages(substream);
817} 825}
818/* 826/*
@@ -829,7 +837,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
829 int err = 0; 837 int err = 0;
830 snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); 838 snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
831 839
832 mutex_lock(&usX2Y->prepare_mutex); 840 mutex_lock(&usX2Y->pcm_mutex);
833 usX2Y_subs_prepare(subs); 841 usX2Y_subs_prepare(subs);
834// Start hardware streams 842// Start hardware streams
835// SyncStream first.... 843// SyncStream first....
@@ -849,7 +857,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
849 err = usX2Y_urbs_start(subs); 857 err = usX2Y_urbs_start(subs);
850 858
851 up_prepare_mutex: 859 up_prepare_mutex:
852 mutex_unlock(&usX2Y->prepare_mutex); 860 mutex_unlock(&usX2Y->pcm_mutex);
853 return err; 861 return err;
854} 862}
855 863
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 814d0e887c62..90766a92e7fd 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -358,7 +358,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
358 struct snd_pcm_runtime *runtime = substream->runtime; 358 struct snd_pcm_runtime *runtime = substream->runtime;
359 struct snd_usX2Y_substream *subs = runtime->private_data, 359 struct snd_usX2Y_substream *subs = runtime->private_data,
360 *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; 360 *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
361 mutex_lock(&subs->usX2Y->prepare_mutex); 361 mutex_lock(&subs->usX2Y->pcm_mutex);
362 snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream); 362 snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
363 363
364 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 364 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -387,7 +387,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
387 usX2Y_usbpcm_urbs_release(cap_subs2); 387 usX2Y_usbpcm_urbs_release(cap_subs2);
388 } 388 }
389 } 389 }
390 mutex_unlock(&subs->usX2Y->prepare_mutex); 390 mutex_unlock(&subs->usX2Y->pcm_mutex);
391 return snd_pcm_lib_free_pages(substream); 391 return snd_pcm_lib_free_pages(substream);
392} 392}
393 393
@@ -493,7 +493,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
493 memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm)); 493 memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
494 } 494 }
495 495
496 mutex_lock(&usX2Y->prepare_mutex); 496 mutex_lock(&usX2Y->pcm_mutex);
497 usX2Y_subs_prepare(subs); 497 usX2Y_subs_prepare(subs);
498// Start hardware streams 498// Start hardware streams
499// SyncStream first.... 499// SyncStream first....
@@ -534,7 +534,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
534 usX2Y->hwdep_pcm_shm->capture_iso_start = -1; 534 usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
535 535
536 up_prepare_mutex: 536 up_prepare_mutex:
537 mutex_unlock(&usX2Y->prepare_mutex); 537 mutex_unlock(&usX2Y->pcm_mutex);
538 return err; 538 return err;
539} 539}
540 540
@@ -600,59 +600,30 @@ static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
600}; 600};
601 601
602 602
603static int usX2Y_pcms_lock_check(struct snd_card *card) 603static int usX2Y_pcms_busy_check(struct snd_card *card)
604{ 604{
605 struct list_head *list; 605 struct usX2Ydev *dev = usX2Y(card);
606 struct snd_device *dev; 606 int i;
607 struct snd_pcm *pcm;
608 int err = 0;
609 list_for_each(list, &card->devices) {
610 dev = snd_device(list);
611 if (dev->type != SNDRV_DEV_PCM)
612 continue;
613 pcm = dev->device_data;
614 mutex_lock(&pcm->open_mutex);
615 }
616 list_for_each(list, &card->devices) {
617 int s;
618 dev = snd_device(list);
619 if (dev->type != SNDRV_DEV_PCM)
620 continue;
621 pcm = dev->device_data;
622 for (s = 0; s < 2; ++s) {
623 struct snd_pcm_substream *substream;
624 substream = pcm->streams[s].substream;
625 if (substream && SUBSTREAM_BUSY(substream))
626 err = -EBUSY;
627 }
628 }
629 return err;
630}
631
632 607
633static void usX2Y_pcms_unlock(struct snd_card *card) 608 for (i = 0; i < dev->pcm_devs * 2; i++) {
634{ 609 struct snd_usX2Y_substream *subs = dev->subs[i];
635 struct list_head *list; 610 if (subs && subs->pcm_substream &&
636 struct snd_device *dev; 611 SUBSTREAM_BUSY(subs->pcm_substream))
637 struct snd_pcm *pcm; 612 return -EBUSY;
638 list_for_each(list, &card->devices) {
639 dev = snd_device(list);
640 if (dev->type != SNDRV_DEV_PCM)
641 continue;
642 pcm = dev->device_data;
643 mutex_unlock(&pcm->open_mutex);
644 } 613 }
614 return 0;
645} 615}
646 616
647
648static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file) 617static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
649{ 618{
650 // we need to be the first
651 struct snd_card *card = hw->card; 619 struct snd_card *card = hw->card;
652 int err = usX2Y_pcms_lock_check(card); 620 int err;
653 if (0 == err) 621
622 mutex_lock(&usX2Y(card)->pcm_mutex);
623 err = usX2Y_pcms_busy_check(card);
624 if (!err)
654 usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS; 625 usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
655 usX2Y_pcms_unlock(card); 626 mutex_unlock(&usX2Y(card)->pcm_mutex);
656 return err; 627 return err;
657} 628}
658 629
@@ -660,10 +631,13 @@ static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
660static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file) 631static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
661{ 632{
662 struct snd_card *card = hw->card; 633 struct snd_card *card = hw->card;
663 int err = usX2Y_pcms_lock_check(card); 634 int err;
664 if (0 == err) 635
636 mutex_lock(&usX2Y(card)->pcm_mutex);
637 err = usX2Y_pcms_busy_check(card);
638 if (!err)
665 usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS; 639 usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
666 usX2Y_pcms_unlock(card); 640 mutex_unlock(&usX2Y(card)->pcm_mutex);
667 return err; 641 return err;
668} 642}
669 643