sound/usb/misc/ua101.c

Source file repositories/reference/linux-study-clean/sound/usb/misc/ua101.c

File Facts

System
Linux kernel
Corpus path
sound/usb/misc/ua101.c
Extension
.c
Size
36567 bytes
Lines
1338
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

struct ua101 {
	struct usb_device *dev;
	struct snd_card *card;
	struct usb_interface *intf[INTF_COUNT];
	int card_index;
	struct snd_pcm *pcm;
	struct list_head midi_list;
	u64 format_bit;
	unsigned int rate;
	unsigned int packets_per_second;
	spinlock_t lock;
	struct mutex mutex;
	unsigned long states;

	/* FIFO to synchronize playback rate to capture rate */
	unsigned int rate_feedback_start;
	unsigned int rate_feedback_count;
	u8 rate_feedback[MAX_QUEUE_LENGTH];

	struct list_head ready_playback_urbs;
	struct work_struct playback_work;
	wait_queue_head_t alsa_capture_wait;
	wait_queue_head_t rate_feedback_wait;
	wait_queue_head_t alsa_playback_wait;
	struct ua101_stream {
		struct snd_pcm_substream *substream;
		unsigned int usb_pipe;
		unsigned int channels;
		unsigned int frame_bytes;
		unsigned int max_packet_bytes;
		unsigned int period_pos;
		unsigned int buffer_pos;
		unsigned int queue_length;
		struct ua101_urb {
			struct urb urb;
			struct usb_iso_packet_descriptor iso_frame_desc[1];
			struct list_head ready_list;
		} *urbs[MAX_QUEUE_LENGTH];
		struct {
			unsigned int size;
			void *addr;
			dma_addr_t dma;
		} buffers[MAX_MEMORY_BUFFERS];
	} capture, playback;
};

static DEFINE_MUTEX(devices_mutex);
static unsigned int devices_used;
static struct usb_driver ua101_driver;

static void abort_alsa_playback(struct ua101 *ua);
static void abort_alsa_capture(struct ua101 *ua);

static const char *usb_error_string(int err)
{
	switch (err) {
	case -ENODEV:
		return "no device";
	case -ENOENT:
		return "endpoint not enabled";
	case -EPIPE:
		return "endpoint stalled";
	case -ENOSPC:
		return "not enough bandwidth";
	case -ESHUTDOWN:
		return "device disabled";
	case -EHOSTUNREACH:
		return "device suspended";
	case -EINVAL:
	case -EAGAIN:
	case -EFBIG:
	case -EMSGSIZE:
		return "internal error";
	default:
		return "unknown error";
	}
}

static void abort_usb_capture(struct ua101 *ua)
{
	if (test_and_clear_bit(USB_CAPTURE_RUNNING, &ua->states)) {
		wake_up(&ua->alsa_capture_wait);
		wake_up(&ua->rate_feedback_wait);
	}
}

static void abort_usb_playback(struct ua101 *ua)
{
	if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
		wake_up(&ua->alsa_playback_wait);

Annotation

Implementation Notes