sound/usb/usx2y/us144mkii_playback.c

Source file repositories/reference/linux-study-clean/sound/usb/usx2y/us144mkii_playback.c

File Facts

System
Linux kernel
Corpus path
sound/usb/usx2y/us144mkii_playback.c
Extension
.c
Size
12986 bytes
Lines
457
Domain
Driver Families
Bucket
sound/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tascam->feedback_synced) {
				frames_for_packet =
					tascam->feedback_accumulator_pattern
						[tascam->feedback_pattern_out_idx];
				tascam->feedback_pattern_out_idx =
					(tascam->feedback_pattern_out_idx + 1) %
					FEEDBACK_ACCUMULATOR_SIZE;
			} else {
				frames_for_packet = runtime->rate / 8000;
			}
			bytes_for_packet = frames_for_packet * BYTES_PER_FRAME;

			urb->iso_frame_desc[i].offset = total_bytes_for_urb;
			urb->iso_frame_desc[i].length = bytes_for_packet;
			total_bytes_for_urb += bytes_for_packet;
		}
		urb->transfer_buffer_length = total_bytes_for_urb;

		offset_frames = tascam->driver_playback_pos;
		frames_to_copy = bytes_to_frames(runtime, total_bytes_for_urb);
		tascam->driver_playback_pos =
			(offset_frames + frames_to_copy) % runtime->buffer_size;
	}

	if (total_bytes_for_urb > 0) {
		u8 *dst_buf = urb->transfer_buffer;

		/* Handle ring buffer wrap-around */
		if (offset_frames + frames_to_copy > runtime->buffer_size) {
			size_t first_chunk_bytes = frames_to_bytes(
				runtime, runtime->buffer_size - offset_frames);
			size_t second_chunk_bytes =
				total_bytes_for_urb - first_chunk_bytes;

			memcpy(dst_buf,
			       runtime->dma_area +
				       frames_to_bytes(runtime, offset_frames),
			       first_chunk_bytes);
			memcpy(dst_buf + first_chunk_bytes, runtime->dma_area,
			       second_chunk_bytes);
		} else {
			memcpy(dst_buf,
			       runtime->dma_area +
				       frames_to_bytes(runtime, offset_frames),
			       total_bytes_for_urb);
		}

		process_playback_routing_us144mkii(tascam, dst_buf, dst_buf,
						   frames_to_copy);
	}

	urb->dev = tascam->dev;
	usb_get_urb(urb);
	usb_anchor_urb(urb, &tascam->playback_anchor);
	ret = usb_submit_urb(urb, GFP_ATOMIC);
	if (ret < 0) {
		dev_err_ratelimited(tascam->card->dev,
				    "Failed to resubmit playback URB: %d\n",
				    ret);
		usb_unanchor_urb(urb);
		usb_put_urb(urb);
		atomic_dec(
			&tascam->active_urbs); /* Decrement on failed resubmission */
	}
out:
	usb_put_urb(urb);
}

void feedback_urb_complete(struct urb *urb)
{
	struct tascam_card *tascam = urb->context;
	struct snd_pcm_substream *playback_ss, *capture_ss;
	struct snd_pcm_runtime *playback_rt, *capture_rt;
	u64 total_frames_in_urb = 0;
	int ret, p;
	unsigned int old_in_idx, new_in_idx;
	bool playback_period_elapsed = false;
	bool capture_period_elapsed = false;

	if (urb->status) {
		if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
		    urb->status != -ESHUTDOWN && urb->status != -ENODEV) {
			dev_err_ratelimited(tascam->card->dev,
					    "Feedback URB failed: %d\n",
					    urb->status);
			atomic_dec(
				&tascam->active_urbs); /* Decrement on failed resubmission */
		}
		goto out;
	}

Annotation

Implementation Notes