Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2233d97 authored by Andrej Krutak's avatar Andrej Krutak Committed by Takashi Iwai
Browse files

ALSA: line6: Enable different number of URBs for frame transfers



This basically changes LINE6_ISO_BUFFERS constant to a configurable
iso_buffers property.

Signed-off-by: default avatarAndrej Krutak <dev@andree.sk>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c5a905d3
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -29,10 +29,10 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
	int ret;
	struct urb *urb_in;

	index =
	    find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS);
	index = find_first_zero_bit(&line6pcm->in.active_urbs,
				    line6pcm->line6->iso_buffers);

	if (index < 0 || index >= LINE6_ISO_BUFFERS) {
	if (index < 0 || index >= line6pcm->line6->iso_buffers) {
		dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
		return -EINVAL;
	}
@@ -73,7 +73,7 @@ int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
{
	int ret = 0, i;

	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
	for (i = 0; i < line6pcm->line6->iso_buffers; ++i) {
		ret = submit_audio_in_urb(line6pcm);
		if (ret < 0)
			break;
@@ -154,7 +154,7 @@ static void audio_in_callback(struct urb *urb)
	line6pcm->in.last_frame = urb->start_frame;

	/* find index of URB */
	for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
	for (index = 0; index < line6pcm->line6->iso_buffers; ++index)
		if (urb == line6pcm->in.urbs[index])
			break;

@@ -247,8 +247,13 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
	struct usb_line6 *line6 = line6pcm->line6;
	int i;

	line6pcm->in.urbs = kzalloc(
		sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL);
	if (line6pcm->in.urbs == NULL)
		return -ENOMEM;

	/* create audio URBs and fill in constant values: */
	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
	for (i = 0; i < line6->iso_buffers; ++i) {
		struct urb *urb;

		/* URB for audio in: */
+1 −0
Original line number Diff line number Diff line
@@ -467,6 +467,7 @@ static void line6_get_interval(struct usb_line6 *line6)
	unsigned epnum = usb_pipeendpoint(pipe);

	ep = usbdev->ep_in[epnum];
	line6->iso_buffers = LINE6_ISO_BUFFERS;
	if (ep) {
		line6->interval = ep->desc.bInterval;
		line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ struct usb_line6 {

	/* Interval (ms) */
	int interval;
	/* Number of isochronous URBs used for frame transfers */
	int iso_buffers;

	/* Maximum size of USB packet */
	int max_packet_size;
+14 −7
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
{
	int i;

	for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
	for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
		if (test_bit(i, &pcms->active_urbs)) {
			if (!test_and_set_bit(i, &pcms->unlink_urbs))
				usb_unlink_urb(pcms->urbs[i]);
@@ -124,7 +124,7 @@ static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,

	do {
		alive = 0;
		for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
		for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
			if (test_bit(i, &pcms->active_urbs))
				alive++;
		}
@@ -153,7 +153,8 @@ static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
{
	/* Invoked multiple times in a row so allocate once only */
	if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) {
		pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
		pstr->buffer = kmalloc(line6pcm->line6->iso_buffers *
				       LINE6_ISO_PACKETS *
				       line6pcm->max_packet_size, GFP_KERNEL);
		if (!pstr->buffer)
			return -ENOMEM;
@@ -434,24 +435,30 @@ static struct snd_kcontrol_new line6_controls[] = {
/*
	Cleanup the PCM device.
*/
static void cleanup_urbs(struct line6_pcm_stream *pcms)
static void cleanup_urbs(struct line6_pcm_stream *pcms, int iso_buffers)
{
	int i;

	for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
	/* Most likely impossible in current code... */
	if (pcms->urbs == NULL)
		return;

	for (i = 0; i < iso_buffers; i++) {
		if (pcms->urbs[i]) {
			usb_kill_urb(pcms->urbs[i]);
			usb_free_urb(pcms->urbs[i]);
		}
	}
	kfree(pcms->urbs);
	pcms->urbs = NULL;
}

static void line6_cleanup_pcm(struct snd_pcm *pcm)
{
	struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);

	cleanup_urbs(&line6pcm->out);
	cleanup_urbs(&line6pcm->in);
	cleanup_urbs(&line6pcm->out, line6pcm->line6->iso_buffers);
	cleanup_urbs(&line6pcm->in, line6pcm->line6->iso_buffers);
	kfree(line6pcm);
}

+1 −1
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ struct line6_pcm_properties {

struct line6_pcm_stream {
	/* allocated URBs */
	struct urb *urbs[LINE6_ISO_BUFFERS];
	struct urb **urbs;

	/* Temporary buffer;
	 * Since the packet size is not known in advance, this buffer is
Loading