> +/** > + * struct snd_soc_usb_device > + * @card_idx - sound card index associated with USB device > + * @pcm_idx - PCM device index associated with USB device > + * @chip_idx - USB sound chip array index > + * @num_playback - number of playback streams > + * @num_capture - number of capture streams so here we have a clear separation between playback and capture... > + * @list - list head for SoC USB devices > + **/ > +struct snd_soc_usb_device { > + int card_idx; > + int pcm_idx; > + int chip_idx; > + int num_playback; > + int num_capture; > + struct list_head list; > +}; > + > +/** > + * struct snd_soc_usb > + * @list - list head for SND SOC struct list > + * @component - reference to ASoC component > + * @num_supported_streams - number of supported concurrent sessions ... but here we don't. And it's not clear what the working 'sessions' means in the comment. > + * @connection_status_cb - callback to notify connection events > + * @priv_data - driver data > + **/ > +struct snd_soc_usb { > + struct list_head list; > + struct snd_soc_component *component; > + unsigned int num_supported_streams; > + int (*connection_status_cb)(struct snd_soc_usb *usb, > + struct snd_soc_usb_device *sdev, bool connected); > + void *priv_data; > +}; > +/** > + * snd_soc_usb_allocate_port() - allocate a SOC USB device USB port? > + * @component: USB DPCM backend DAI component > + * @num_streams: number of offloading sessions supported same comment, is this direction-specific or not? > + * @data: private data > + * > + * Allocate and initialize a SOC USB device. This will populate parameters that > + * are used in subsequent sequences. > + * > + */ > +struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *component, > + int num_streams, void *data) > +{ > + struct snd_soc_usb *usb; > + > + usb = kzalloc(sizeof(*usb), GFP_KERNEL); > + if (!usb) > + return ERR_PTR(-ENOMEM); > + > + usb->component = component; > + usb->priv_data = data; > + usb->num_supported_streams = num_streams; > + > + return usb; > +} > +EXPORT_SYMBOL_GPL(snd_soc_usb_allocate_port); > + > +/** > + * snd_soc_usb_free_port() - free a SOC USB device > + * @usb: allocated SOC USB device > + > + * Free and remove the SOC USB device from the available list of devices. Now I am lost again on the device:port relationship. I am sure you've explained this before but I forget things and the code isn't self-explanatory. > + * > + */ > +void snd_soc_usb_free_port(struct snd_soc_usb *usb) > +{ > + snd_soc_usb_remove_port(usb); > + kfree(usb); > +} > +EXPORT_SYMBOL_GPL(snd_soc_usb_free_port); > + > +/** > + * snd_soc_usb_add_port() - Add a USB backend port > + * @usb: soc usb device to add > + * > + * Register a USB backend device to the SND USB SOC framework. Memory is > + * allocated as part of the USB backend device. > + * > + */ > +void snd_soc_usb_add_port(struct snd_soc_usb *usb) > +{ > + mutex_lock(&ctx_mutex); > + list_add_tail(&usb->list, &usb_ctx_list); > + mutex_unlock(&ctx_mutex); > +} > +EXPORT_SYMBOL_GPL(snd_soc_usb_add_port); > + > +/** > + * snd_soc_usb_remove_port() - Remove a USB backend port > + * @usb: soc usb device to remove > + * > + * Remove a USB backend device from USB SND SOC. Memory is freed when USB > + * backend is removed. > + * > + */ > +void snd_soc_usb_remove_port(struct snd_soc_usb *usb) > +{ > + struct snd_soc_usb *ctx, *tmp; > + > + mutex_lock(&ctx_mutex); > + list_for_each_entry_safe(ctx, tmp, &usb_ctx_list, list) { > + if (ctx == usb) { > + list_del(&ctx->list); > + break; > + } > + } > + mutex_unlock(&ctx_mutex); > +} > +EXPORT_SYMBOL_GPL(snd_soc_usb_remove_port);