mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Revert "ALSA: usb-audio: Refcount multiple accesses on the single clock"
This reverts commit9830e7383fwhich is commitc11117b634upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I118d9b1069bcc55b41a2353ecd4e00d42c301cec Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -645,7 +645,6 @@ static int snd_usb_audio_create(struct usb_interface *intf,
|
||||
INIT_LIST_HEAD(&chip->pcm_list);
|
||||
INIT_LIST_HEAD(&chip->ep_list);
|
||||
INIT_LIST_HEAD(&chip->iface_ref_list);
|
||||
INIT_LIST_HEAD(&chip->clock_ref_list);
|
||||
INIT_LIST_HEAD(&chip->midi_list);
|
||||
INIT_LIST_HEAD(&chip->mixer_list);
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ struct audioformat {
|
||||
|
||||
struct snd_usb_substream;
|
||||
struct snd_usb_iface_ref;
|
||||
struct snd_usb_clock_ref;
|
||||
struct snd_usb_endpoint;
|
||||
struct snd_usb_power_domain;
|
||||
|
||||
@@ -65,7 +64,6 @@ struct snd_urb_ctx {
|
||||
struct snd_usb_endpoint {
|
||||
struct snd_usb_audio *chip;
|
||||
struct snd_usb_iface_ref *iface_ref;
|
||||
struct snd_usb_clock_ref *clock_ref;
|
||||
|
||||
int opened; /* open refcount; protect with chip->mutex */
|
||||
atomic_t running; /* running status */
|
||||
@@ -142,6 +140,7 @@ struct snd_usb_endpoint {
|
||||
unsigned int cur_period_frames;
|
||||
unsigned int cur_period_bytes;
|
||||
unsigned int cur_buffer_periods;
|
||||
unsigned char cur_clock;
|
||||
|
||||
spinlock_t lock;
|
||||
struct list_head list;
|
||||
|
||||
@@ -37,14 +37,6 @@ struct snd_usb_iface_ref {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* clock refcounting */
|
||||
struct snd_usb_clock_ref {
|
||||
unsigned char clock;
|
||||
atomic_t locked;
|
||||
int rate;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/*
|
||||
* snd_usb_endpoint is a model that abstracts everything related to an
|
||||
* USB endpoint and its streaming.
|
||||
@@ -608,25 +600,6 @@ iface_ref_find(struct snd_usb_audio *chip, int iface)
|
||||
return ip;
|
||||
}
|
||||
|
||||
/* Similarly, a refcount object for clock */
|
||||
static struct snd_usb_clock_ref *
|
||||
clock_ref_find(struct snd_usb_audio *chip, int clock)
|
||||
{
|
||||
struct snd_usb_clock_ref *ref;
|
||||
|
||||
list_for_each_entry(ref, &chip->clock_ref_list, list)
|
||||
if (ref->clock == clock)
|
||||
return ref;
|
||||
|
||||
ref = kzalloc(sizeof(*ref), GFP_KERNEL);
|
||||
if (!ref)
|
||||
return NULL;
|
||||
ref->clock = clock;
|
||||
atomic_set(&ref->locked, 0);
|
||||
list_add_tail(&ref->list, &chip->clock_ref_list);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the existing endpoint object corresponding EP
|
||||
* Returns NULL if not present.
|
||||
@@ -804,14 +777,6 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (fp->protocol != UAC_VERSION_1) {
|
||||
ep->clock_ref = clock_ref_find(chip, fp->clock);
|
||||
if (!ep->clock_ref) {
|
||||
ep = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
ep->cur_audiofmt = fp;
|
||||
ep->cur_channels = fp->channels;
|
||||
ep->cur_rate = params_rate(params);
|
||||
@@ -821,6 +786,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
|
||||
ep->cur_period_frames = params_period_size(params);
|
||||
ep->cur_period_bytes = ep->cur_period_frames * ep->cur_frame_bytes;
|
||||
ep->cur_buffer_periods = params_periods(params);
|
||||
ep->cur_clock = fp->clock;
|
||||
|
||||
if (ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
|
||||
endpoint_set_syncinterval(chip, ep);
|
||||
@@ -939,8 +905,8 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
|
||||
ep->altsetting = 0;
|
||||
ep->cur_audiofmt = NULL;
|
||||
ep->cur_rate = 0;
|
||||
ep->cur_clock = 0;
|
||||
ep->iface_ref = NULL;
|
||||
ep->clock_ref = NULL;
|
||||
usb_audio_dbg(chip, "EP 0x%x closed\n", ep->ep_num);
|
||||
}
|
||||
mutex_unlock(&chip->mutex);
|
||||
@@ -953,8 +919,6 @@ void snd_usb_endpoint_suspend(struct snd_usb_endpoint *ep)
|
||||
ep->need_setup = true;
|
||||
if (ep->iface_ref)
|
||||
ep->iface_ref->need_setup = true;
|
||||
if (ep->clock_ref)
|
||||
ep->clock_ref->rate = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1361,33 +1325,6 @@ static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_sample_rate(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
{
|
||||
struct snd_usb_clock_ref *clock = ep->clock_ref;
|
||||
int err;
|
||||
|
||||
if (clock) {
|
||||
if (atomic_read(&clock->locked))
|
||||
return 0;
|
||||
if (clock->rate == ep->cur_rate)
|
||||
return 0;
|
||||
if (clock->rate && clock->rate != ep->cur_rate) {
|
||||
usb_audio_dbg(chip, "Mismatched sample rate %d vs %d for EP 0x%x\n",
|
||||
clock->rate, ep->cur_rate, ep->ep_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt, ep->cur_rate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (clock)
|
||||
clock->rate = ep->cur_rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_usb_endpoint_configure: Configure the endpoint
|
||||
*
|
||||
@@ -1417,7 +1354,8 @@ int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
|
||||
* to update at each EP configuration
|
||||
*/
|
||||
if (ep->cur_audiofmt->protocol == UAC_VERSION_1) {
|
||||
err = init_sample_rate(chip, ep);
|
||||
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt,
|
||||
ep->cur_rate);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
}
|
||||
@@ -1447,7 +1385,7 @@ int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = init_sample_rate(chip, ep);
|
||||
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt, ep->cur_rate);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
@@ -1481,15 +1419,15 @@ EXPORT_SYMBOL_GPL(snd_usb_endpoint_configure);
|
||||
/* get the current rate set to the given clock by any endpoint */
|
||||
int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock)
|
||||
{
|
||||
struct snd_usb_clock_ref *ref;
|
||||
struct snd_usb_endpoint *ep;
|
||||
int rate = 0;
|
||||
|
||||
if (!clock)
|
||||
return 0;
|
||||
mutex_lock(&chip->mutex);
|
||||
list_for_each_entry(ref, &chip->clock_ref_list, list) {
|
||||
if (ref->clock == clock) {
|
||||
rate = ref->rate;
|
||||
list_for_each_entry(ep, &chip->ep_list, list) {
|
||||
if (ep->cur_clock == clock && ep->cur_rate) {
|
||||
rate = ep->cur_rate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1530,9 +1468,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
|
||||
if (atomic_inc_return(&ep->running) != 1)
|
||||
return 0;
|
||||
|
||||
if (ep->clock_ref)
|
||||
atomic_inc(&ep->clock_ref->locked);
|
||||
|
||||
ep->active_mask = 0;
|
||||
ep->unlink_mask = 0;
|
||||
ep->phase = 0;
|
||||
@@ -1644,9 +1579,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool keep_pending)
|
||||
if (ep->sync_source)
|
||||
WRITE_ONCE(ep->sync_source->sync_sink, NULL);
|
||||
stop_urbs(ep, false, keep_pending);
|
||||
if (ep->clock_ref)
|
||||
if (!atomic_dec_return(&ep->clock_ref->locked))
|
||||
ep->clock_ref->rate = 0;
|
||||
|
||||
trace_android_vh_audio_usb_offload_ep_action(ep, false);
|
||||
}
|
||||
@@ -1675,16 +1607,12 @@ void snd_usb_endpoint_free_all(struct snd_usb_audio *chip)
|
||||
{
|
||||
struct snd_usb_endpoint *ep, *en;
|
||||
struct snd_usb_iface_ref *ip, *in;
|
||||
struct snd_usb_clock_ref *cp, *cn;
|
||||
|
||||
list_for_each_entry_safe(ep, en, &chip->ep_list, list)
|
||||
kfree(ep);
|
||||
|
||||
list_for_each_entry_safe(ip, in, &chip->iface_ref_list, list)
|
||||
kfree(ip);
|
||||
|
||||
list_for_each_entry_safe(cp, cn, &chip->clock_ref_list, list)
|
||||
kfree(ip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -48,7 +48,6 @@ struct snd_usb_audio {
|
||||
struct list_head pcm_list; /* list of pcm streams */
|
||||
struct list_head ep_list; /* list of audio-related endpoints */
|
||||
struct list_head iface_ref_list; /* list of interface refcounts */
|
||||
struct list_head clock_ref_list; /* list of clock refcounts */
|
||||
int pcm_devs;
|
||||
|
||||
struct list_head midi_list; /* list of midi interfaces */
|
||||
|
||||
Reference in New Issue
Block a user