aboutsummaryrefslogtreecommitdiff
path: root/sound/usb/usx2y
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usx2y')
-rw-r--r--sound/usb/usx2y/us122l.c32
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c2
-rw-r--r--sound/usb/usx2y/usb_stream.c7
-rw-r--r--sound/usb/usx2y/usbusx2y.c38
-rw-r--r--sound/usb/usx2y/usbusx2y.h2
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c93
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c92
7 files changed, 102 insertions, 164 deletions
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 084e6fc8d5b..cf5dc33f4a6 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
+#include <linux/module.h>
#include <sound/core.h>
#include <sound/hwdep.h>
#include <sound/pcm.h>
@@ -36,7 +37,7 @@ MODULE_LICENSE("GPL");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
/* Enable this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
@@ -261,7 +262,9 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
}
area->vm_ops = &usb_stream_hwdep_vm_ops;
- area->vm_flags |= VM_RESERVED;
+ area->vm_flags |= VM_DONTDUMP;
+ if (!read)
+ area->vm_flags |= VM_DONTEXPAND;
area->vm_private_data = us122l;
atomic_inc(&us122l->mmap_count);
out:
@@ -532,7 +535,9 @@ static void snd_us122l_free(struct snd_card *card)
snd_us122l_card_used[index] = 0;
}
-static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
+static int usx2y_create_card(struct usb_device *device,
+ struct usb_interface *intf,
+ struct snd_card **cardp)
{
int dev;
struct snd_card *card;
@@ -543,8 +548,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
break;
if (dev >= SNDRV_CARDS)
return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct us122l), &card);
+ err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
+ sizeof(struct us122l), &card);
if (err < 0)
return err;
snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
@@ -575,11 +580,10 @@ static int us122l_usb_probe(struct usb_interface *intf,
struct snd_card *card;
int err;
- err = usx2y_create_card(device, &card);
+ err = usx2y_create_card(device, intf, &card);
if (err < 0)
return err;
- snd_card_set_dev(card, &intf->dev);
if (!us122l_create_card(card)) {
snd_card_free(card);
return -EINVAL;
@@ -771,16 +775,4 @@ static struct usb_driver snd_us122l_usb_driver = {
.supports_autosuspend = 1
};
-
-static int __init snd_us122l_module_init(void)
-{
- return usb_register(&snd_us122l_usb_driver);
-}
-
-static void __exit snd_us122l_module_exit(void)
-{
- usb_deregister(&snd_us122l_usb_driver);
-}
-
-module_init(snd_us122l_module_init)
-module_exit(snd_us122l_module_exit)
+module_usb_driver(snd_us122l_usb_driver);
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 04aafb43a13..0b34dbc8f30 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -82,7 +82,7 @@ static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct v
us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
}
area->vm_ops = &us428ctls_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
return 0;
}
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index c400ade3ff0..bf618e1500a 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -69,7 +69,6 @@ static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
++u, transfer += transfer_length) {
struct urb *urb = urbs[u];
struct usb_iso_packet_descriptor *desc;
- urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = transfer;
urb->dev = dev;
urb->pipe = pipe;
@@ -674,7 +673,7 @@ dotry:
inurb->transfer_buffer_length =
inurb->number_of_packets *
inurb->iso_frame_desc[0].length;
- preempt_disable();
+
if (u == 0) {
int now;
struct usb_device *dev = inurb->dev;
@@ -686,19 +685,17 @@ dotry:
}
err = usb_submit_urb(inurb, GFP_ATOMIC);
if (err < 0) {
- preempt_enable();
snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
" returned %i\n", u, err);
return err;
}
err = usb_submit_urb(outurb, GFP_ATOMIC);
if (err < 0) {
- preempt_enable();
snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
" returned %i\n", u, err);
return err;
}
- preempt_enable();
+
if (inurb->start_frame != outurb->start_frame) {
snd_printd(KERN_DEBUG
"u[%i] start_frames differ in:%u out:%u\n",
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index cbd37f2c76d..91e0e2a4808 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -150,11 +150,11 @@
MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
+MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}");
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_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
@@ -305,11 +305,9 @@ static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
{
int i;
for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (S[i].urb) {
- usb_kill_urb(S->urb[i]);
- usb_free_urb(S->urb[i]);
- S->urb[i] = NULL;
- }
+ usb_kill_urb(S->urb[i]);
+ usb_free_urb(S->urb[i]);
+ S->urb[i] = NULL;
}
kfree(S->buffer);
}
@@ -334,7 +332,9 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = {
{ /* terminator */ }
};
-static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
+static int usX2Y_create_card(struct usb_device *device,
+ struct usb_interface *intf,
+ struct snd_card **cardp)
{
int dev;
struct snd_card * card;
@@ -345,15 +345,15 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
break;
if (dev >= SNDRV_CARDS)
return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct usX2Ydev), &card);
+ err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
+ sizeof(struct usX2Ydev), &card);
if (err < 0)
return err;
snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
card->private_free = snd_usX2Y_card_private_free;
usX2Y(card)->dev = device;
init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
- mutex_init(&usX2Y(card)->prepare_mutex);
+ mutex_init(&usX2Y(card)->pcm_mutex);
INIT_LIST_HEAD(&usX2Y(card)->midi_list);
strcpy(card->driver, "USB "NAME_ALLCAPS"");
sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
@@ -384,10 +384,9 @@ static int usX2Y_usb_probe(struct usb_device *device,
le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
return -EINVAL;
- err = usX2Y_create_card(device, &card);
+ err = usX2Y_create_card(device, intf, &card);
if (err < 0)
return err;
- snd_card_set_dev(card, &intf->dev);
if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
(err = snd_card_register(card)) < 0) {
snd_card_free(card);
@@ -459,15 +458,4 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
}
}
-static int __init snd_usX2Y_module_init(void)
-{
- return usb_register(&snd_usX2Y_usb_driver);
-}
-
-static void __exit snd_usX2Y_module_exit(void)
-{
- usb_deregister(&snd_usX2Y_usb_driver);
-}
-
-module_init(snd_usX2Y_module_init)
-module_exit(snd_usX2Y_module_exit)
+module_usb_driver(snd_usX2Y_usb_driver);
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index e43c0a86441..6ae6b080693 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -36,7 +36,7 @@ struct usX2Ydev {
unsigned int rate,
format;
int chip_status;
- struct mutex prepare_mutex;
+ struct mutex pcm_mutex;
struct us428ctls_sharedmem *us428ctls_sharedmem;
int wait_iso_frame;
wait_queue_head_t us428ctls_wait_queue_head;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 5d37d1ccf81..a63330dd140 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -34,6 +34,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/usb.h>
+#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/pcm.h>
@@ -79,7 +80,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
snd_printk(KERN_ERR "active frame status %i. "
- "Most propably some hardware problem.\n",
+ "Most probably some hardware problem.\n",
urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
@@ -272,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
struct snd_usX2Y_substream *subs = usX2Y->subs[s];
if (subs) {
if (atomic_read(&subs->state) >= state_PRERUNNING) {
+ unsigned long flags;
+
+ snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags);
snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+ snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags);
}
for (u = 0; u < NRURBS; u++) {
struct urb *urb = subs->urb[u];
@@ -294,19 +299,6 @@ static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
usX2Y_clients_stop(usX2Y);
}
-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR
-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-"Most propably some urb of usb-frame %i is still missing.\n"
-"Cause could be too long delays in usb-hcd interrupt handling.\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
- usX2Y_clients_stop(usX2Y);
-}
-
static void i_usX2Y_urb_complete(struct urb *urb)
{
struct snd_usX2Y_substream *subs = urb->context;
@@ -323,12 +315,9 @@ static void i_usX2Y_urb_complete(struct urb *urb)
usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
+
+ subs->completed_urb = urb;
+
{
struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
@@ -502,7 +491,6 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
if (0 == i)
atomic_set(&subs->state, state_STARTING3);
urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
for (pack = 0; pack < nr_of_packs(); pack++) {
urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
urb->iso_frame_desc[pack].length = subs->maxpacksize;
@@ -695,9 +683,6 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
((char*)(usbdata + i))[1] = ra[i].c2;
usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
usbdata + i, 2, i_usX2Y_04Int, usX2Y);
-#ifdef OLD_USB
- us->urb[i]->transfer_flags = USB_QUEUE_BULK;
-#endif
}
us->submitted = 0;
us->len = NOOF_SETRATE_URBS;
@@ -767,36 +752,44 @@ static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int rate = params_rate(hw_params);
snd_pcm_format_t format = params_format(hw_params);
struct snd_card *card = substream->pstr->pcm->card;
- struct list_head *list;
+ struct usX2Ydev *dev = usX2Y(card);
+ int i;
+ mutex_lock(&usX2Y(card)->pcm_mutex);
snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
- // all pcm substreams off one usX2Y have to operate at the same rate & format
- list_for_each(list, &card->devices) {
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
+ /* all pcm substreams off one usX2Y have to operate at the same
+ * rate & format
+ */
+ for (i = 0; i < dev->pcm_devs * 2; i++) {
+ struct snd_usX2Y_substream *subs = dev->subs[i];
+ struct snd_pcm_substream *test_substream;
+
+ if (!subs)
+ continue;
+ test_substream = subs->pcm_substream;
+ if (!test_substream || test_substream == substream ||
+ !test_substream->runtime)
continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *test_substream;
- test_substream = pcm->streams[s].substream;
- if (test_substream && test_substream != substream &&
- test_substream->runtime &&
- ((test_substream->runtime->format &&
- test_substream->runtime->format != format) ||
- (test_substream->runtime->rate &&
- test_substream->runtime->rate != rate)))
- return -EINVAL;
+ if ((test_substream->runtime->format &&
+ test_substream->runtime->format != format) ||
+ (test_substream->runtime->rate &&
+ test_substream->runtime->rate != rate)) {
+ err = -EINVAL;
+ goto error;
}
}
- if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
+
+ err = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (err < 0) {
snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
substream, params_buffer_bytes(hw_params), err);
- return err;
+ goto error;
}
- return 0;
+
+ error:
+ mutex_unlock(&usX2Y(card)->pcm_mutex);
+ return err;
}
/*
@@ -806,7 +799,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_usX2Y_substream *subs = runtime->private_data;
- mutex_lock(&subs->usX2Y->prepare_mutex);
+ mutex_lock(&subs->usX2Y->pcm_mutex);
snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -827,7 +820,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
usX2Y_urbs_release(subs);
}
}
- mutex_unlock(&subs->usX2Y->prepare_mutex);
+ mutex_unlock(&subs->usX2Y->pcm_mutex);
return snd_pcm_lib_free_pages(substream);
}
/*
@@ -844,7 +837,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
int err = 0;
snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
- mutex_lock(&usX2Y->prepare_mutex);
+ mutex_lock(&usX2Y->pcm_mutex);
usX2Y_subs_prepare(subs);
// Start hardware streams
// SyncStream first....
@@ -864,7 +857,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
err = usX2Y_urbs_start(subs);
up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
+ mutex_unlock(&usX2Y->pcm_mutex);
return err;
}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 287ef73b123..90766a92e7f 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -20,7 +20,7 @@
at standard samplerates,
what led to this part of the usx2y module:
It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
- The pair uses a hardware dependant alsa-device for mmaped pcm transport.
+ The pair uses a hardware dependent alsa-device for mmaped pcm transport.
Advantage achieved:
The usb_hc moves pcm data from/into memory via DMA.
That memory is mmaped by jack's usx2y driver.
@@ -38,7 +38,7 @@
2periods works but is useless cause of crackling).
This is a first "proof of concept" implementation.
- Later, functionalities should migrate to more apropriate places:
+ Later, functionalities should migrate to more appropriate places:
Userland:
- The jackd could mmap its float-pcm buffers directly from alsa-lib.
- alsa-lib could provide power of 2 period sized shaping combined with int/float
@@ -74,7 +74,7 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
}
for (i = 0; i < nr_of_packs(); i++) {
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+ snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -244,13 +244,8 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
+ subs->completed_urb = urb;
capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
@@ -363,7 +358,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_usX2Y_substream *subs = runtime->private_data,
*cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- mutex_lock(&subs->usX2Y->prepare_mutex);
+ mutex_lock(&subs->usX2Y->pcm_mutex);
snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -392,7 +387,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
usX2Y_usbpcm_urbs_release(cap_subs2);
}
}
- mutex_unlock(&subs->usX2Y->prepare_mutex);
+ mutex_unlock(&subs->usX2Y->pcm_mutex);
return snd_pcm_lib_free_pages(substream);
}
@@ -443,7 +438,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
if (0 == u)
atomic_set(&subs->state, state_STARTING3);
urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
for (pack = 0; pack < nr_of_packs(); pack++) {
urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
urb->iso_frame_desc[pack].length = subs->maxpacksize;
@@ -499,7 +493,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
}
- mutex_lock(&usX2Y->prepare_mutex);
+ mutex_lock(&usX2Y->pcm_mutex);
usX2Y_subs_prepare(subs);
// Start hardware streams
// SyncStream first....
@@ -540,7 +534,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
+ mutex_unlock(&usX2Y->pcm_mutex);
return err;
}
@@ -606,59 +600,30 @@ static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
};
-static int usX2Y_pcms_lock_check(struct snd_card *card)
+static int usX2Y_pcms_busy_check(struct snd_card *card)
{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int err = 0;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_lock(&pcm->open_mutex);
- }
- list_for_each(list, &card->devices) {
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *substream;
- substream = pcm->streams[s].substream;
- if (substream && SUBSTREAM_BUSY(substream))
- err = -EBUSY;
- }
- }
- return err;
-}
-
+ struct usX2Ydev *dev = usX2Y(card);
+ int i;
-static void usX2Y_pcms_unlock(struct snd_card *card)
-{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_unlock(&pcm->open_mutex);
+ for (i = 0; i < dev->pcm_devs * 2; i++) {
+ struct snd_usX2Y_substream *subs = dev->subs[i];
+ if (subs && subs->pcm_substream &&
+ SUBSTREAM_BUSY(subs->pcm_substream))
+ return -EBUSY;
}
+ return 0;
}
-
static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
{
- // we need to be the first
struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
+ int err;
+
+ mutex_lock(&usX2Y(card)->pcm_mutex);
+ err = usX2Y_pcms_busy_check(card);
+ if (!err)
usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
+ mutex_unlock(&usX2Y(card)->pcm_mutex);
return err;
}
@@ -666,10 +631,13 @@ static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
{
struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
+ int err;
+
+ mutex_lock(&usX2Y(card)->pcm_mutex);
+ err = usX2Y_pcms_busy_check(card);
+ if (!err)
usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
+ mutex_unlock(&usX2Y(card)->pcm_mutex);
return err;
}
@@ -723,7 +691,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st
return -ENODEV;
}
area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
return 0;
}