On 07/01/21 01:01, Ethin Probst wrote: > Hi all, > So Leif and I have been working on USB Audio but we've run into a snag. We've > encountered a problem -- neither of us knows enough about USB to figure out > how to get the class-specific AC interface descriptors, and those contain > vital information that I need to be able to control the audio device. The > audio specification was quite useless. So I have two projects running in > parallel: the USB audio one and the VirtIO audio (We managed to get the > virtio-snd patchset in qemu and I've got a built version of it over here and, > though its not a fully working implementation, as long as I get something -- > no matter how bad it sounds -- I'll be happy). Whichever project we get > working first is the one we move forward with. > The VirtIO sound device specification contains four virtqueues: the control > queue for controlling the device; the event queue for receiving notifications > from the device; the tx queue for transmitting audio data to the device; and > the rx queue for receiving audio data from the device. Thus far I've been > following the VirtioRngDxe code as a guide on how to get a VirtIO device > initialized using the VirtioLib in OVMF, but I've reached an impasse > regarding the queues and descriptors. > > The VirtioRngDxe DXE uses a single descriptor and a single queue for > operation. However, the RNG device works vastly differently to the audio > device and is far simpler. The virtio-snd specification says that, to > initialize the device, I must (copied from the spec): > > * Configure the control, event, tx and rx queues. > * Read the jacks field and send a control request to query information about > the available jacks. > * Read the streams field and send a control request to query information > about the available PCM streams. > * Read the chmaps field and send a control request to query information about > the available channel maps. > * Populate the event queue with empty buffers. > > Steps 2, 3, 4, and 5 are a bit confusing and raise some questions: > > 1. Does the device automatically send notifications in the event queue about > the jacks, streams, and channel maps, or do I have to explicitly ask for them? > 2. How many buffers would we need to populate the event queue with, and what > VirtioLib function (if any) specifically accomplishes that?
What you describe here makes the virtio-sound device the most complex virtio device that OVMF has ever had any interest in. The only driver you can use as an example is VirtioNetDxe. VirtioRngDxe is about the simplest virtio device / driver, but for an example here, you need to be looking at the opposite end of the spectrum. For the duplex communication, please refer in particular to "OvmfPkg/VirtioNetDxe/TechNotes.txt". In virtio, requests are always created by the driver (= the guest), and requests are always completed by the device (= the host). Therefore, for asynchronous host-to-guest communication, the guest has to fully pre-populate the affected queues with requests, and when host actions arrive (technically presented as "request completions"), the guest has to process those "completions" and re-populate the affected queue at once to the brim. VirtioLib provides a number of utility / convenience functions, for various areas / actions. However, the VirtioPrepare(), VirtioAppendDesc(), VirtioFlush() functions in particular are inappropriate for your use case. Those helper functions implement a simple, synchronous request-response pattern, building and submitting a single descriptor chain, and blocking until the host reports that chain processed. These functions exist because this simple pattern is suitable for most of the virtio drivers (VirtioBlkDxe, VirtioFsDxe, VirtioGpuDxe, VirtioRngDxe, VirtioScsiDxe). The reason being that the UEFI protocols implemented all support the same, simple, synchronous pattern. These functions are however not helpful for actual async communication, so they are not used in VirtioNetDxe -- VirtioNetDxe does its own queue and descriptor chain management. (It's documented in detail in "TechNotes.txt".) To be honest, I would recommend abandoning the virtio-sound path for now. The virtio programming will eat up a huge amount of your time, and that's not what you want to be concentrating on. I had had no previous experience with either audio programming or the virtio-sound device itself; TBH I didn't expect this level of complexity (in particular, based on your description, that *all four* queues would have to be initialized, no questions asked). The virtio drivers in OVMF are always kept as simple as possible, only the inevitably necessary queues are initialized (and the devices are configured accordingly), and only the simplest communication patterns are used. These drivers are not OS drivers; what they need to do is "facilitate booting". Example: the BlockIo protocol only supports synchronous requests, whereas the BlockIo2 protocol supports asynchronous requests as well. Technically speaking, virtio is fully capable of implementing the asynchrony of BlockIo2, so (e.g.) a BlockIo2 protocol implementation on top of virtio-blk would be possible. But why bother? It just complicates the code a whole lot, and booting an OS with just BlockIo is sufficiently fast already. VirtioNetDxe *must* be different however, because the UEFI-level abstraction, SimpleNetworkProtocol (SNP), is truly asynchronous itself. If you can design a UEFI protocol for just sound *output* that lets you get away with synchronous (blocking) UEFI protocol member function calls, then you *might* be able to ignore most of the virtio-sound complexity, and use the existent descriptor chain management functions in VirtioLib. You could perhaps ignore the "event" and "rx" queues altogether, and use the synchronous VirtioLib functions for both "control" requests and actual audio output ("tx"). I can't tell. Thanks Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#77443): https://edk2.groups.io/g/devel/message/77443 Mute This Topic: https://groups.io/mt/83904983/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-