Mention branches and keyring.
[releases.git] / virtio / virtio_card.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * virtio-snd: Virtio sound device
4  * Copyright (C) 2021 OpenSynergy GmbH
5  */
6 #include <linux/module.h>
7 #include <linux/moduleparam.h>
8 #include <linux/virtio_config.h>
9 #include <sound/initval.h>
10 #include <uapi/linux/virtio_ids.h>
11
12 #include "virtio_card.h"
13
14 u32 virtsnd_msg_timeout_ms = MSEC_PER_SEC;
15 module_param_named(msg_timeout_ms, virtsnd_msg_timeout_ms, uint, 0644);
16 MODULE_PARM_DESC(msg_timeout_ms, "Message completion timeout in milliseconds");
17
18 static void virtsnd_remove(struct virtio_device *vdev);
19
20 /**
21  * virtsnd_event_send() - Add an event to the event queue.
22  * @vqueue: Underlying event virtqueue.
23  * @event: Event.
24  * @notify: Indicates whether or not to send a notification to the device.
25  * @gfp: Kernel flags for memory allocation.
26  *
27  * Context: Any context.
28  */
29 static void virtsnd_event_send(struct virtqueue *vqueue,
30                                struct virtio_snd_event *event, bool notify,
31                                gfp_t gfp)
32 {
33         struct scatterlist sg;
34         struct scatterlist *psgs[1] = { &sg };
35
36         /* reset event content */
37         memset(event, 0, sizeof(*event));
38
39         sg_init_one(&sg, event, sizeof(*event));
40
41         if (virtqueue_add_sgs(vqueue, psgs, 0, 1, event, gfp) || !notify)
42                 return;
43
44         if (virtqueue_kick_prepare(vqueue))
45                 virtqueue_notify(vqueue);
46 }
47
48 /**
49  * virtsnd_event_dispatch() - Dispatch an event from the device side.
50  * @snd: VirtIO sound device.
51  * @event: VirtIO sound event.
52  *
53  * Context: Any context.
54  */
55 static void virtsnd_event_dispatch(struct virtio_snd *snd,
56                                    struct virtio_snd_event *event)
57 {
58         switch (le32_to_cpu(event->hdr.code)) {
59         case VIRTIO_SND_EVT_JACK_CONNECTED:
60         case VIRTIO_SND_EVT_JACK_DISCONNECTED:
61                 virtsnd_jack_event(snd, event);
62                 break;
63         case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
64         case VIRTIO_SND_EVT_PCM_XRUN:
65                 virtsnd_pcm_event(snd, event);
66                 break;
67         }
68 }
69
70 /**
71  * virtsnd_event_notify_cb() - Dispatch all reported events from the event queue.
72  * @vqueue: Underlying event virtqueue.
73  *
74  * This callback function is called upon a vring interrupt request from the
75  * device.
76  *
77  * Context: Interrupt context.
78  */
79 static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
80 {
81         struct virtio_snd *snd = vqueue->vdev->priv;
82         struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
83         struct virtio_snd_event *event;
84         u32 length;
85         unsigned long flags;
86
87         spin_lock_irqsave(&queue->lock, flags);
88         do {
89                 virtqueue_disable_cb(vqueue);
90                 while ((event = virtqueue_get_buf(vqueue, &length))) {
91                         virtsnd_event_dispatch(snd, event);
92                         virtsnd_event_send(vqueue, event, true, GFP_ATOMIC);
93                 }
94         } while (!virtqueue_enable_cb(vqueue));
95         spin_unlock_irqrestore(&queue->lock, flags);
96 }
97
98 /**
99  * virtsnd_find_vqs() - Enumerate and initialize all virtqueues.
100  * @snd: VirtIO sound device.
101  *
102  * After calling this function, the event queue is disabled.
103  *
104  * Context: Any context.
105  * Return: 0 on success, -errno on failure.
106  */
107 static int virtsnd_find_vqs(struct virtio_snd *snd)
108 {
109         struct virtio_device *vdev = snd->vdev;
110         static vq_callback_t *callbacks[VIRTIO_SND_VQ_MAX] = {
111                 [VIRTIO_SND_VQ_CONTROL] = virtsnd_ctl_notify_cb,
112                 [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb,
113                 [VIRTIO_SND_VQ_TX] = virtsnd_pcm_tx_notify_cb,
114                 [VIRTIO_SND_VQ_RX] = virtsnd_pcm_rx_notify_cb
115         };
116         static const char *names[VIRTIO_SND_VQ_MAX] = {
117                 [VIRTIO_SND_VQ_CONTROL] = "virtsnd-ctl",
118                 [VIRTIO_SND_VQ_EVENT] = "virtsnd-event",
119                 [VIRTIO_SND_VQ_TX] = "virtsnd-tx",
120                 [VIRTIO_SND_VQ_RX] = "virtsnd-rx"
121         };
122         struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 };
123         unsigned int i;
124         unsigned int n;
125         int rc;
126
127         rc = virtio_find_vqs(vdev, VIRTIO_SND_VQ_MAX, vqs, callbacks, names,
128                              NULL);
129         if (rc) {
130                 dev_err(&vdev->dev, "failed to initialize virtqueues\n");
131                 return rc;
132         }
133
134         for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i)
135                 snd->queues[i].vqueue = vqs[i];
136
137         /* Allocate events and populate the event queue */
138         virtqueue_disable_cb(vqs[VIRTIO_SND_VQ_EVENT]);
139
140         n = virtqueue_get_vring_size(vqs[VIRTIO_SND_VQ_EVENT]);
141
142         snd->event_msgs = kmalloc_array(n, sizeof(*snd->event_msgs),
143                                         GFP_KERNEL);
144         if (!snd->event_msgs)
145                 return -ENOMEM;
146
147         for (i = 0; i < n; ++i)
148                 virtsnd_event_send(vqs[VIRTIO_SND_VQ_EVENT],
149                                    &snd->event_msgs[i], false, GFP_KERNEL);
150
151         return 0;
152 }
153
154 /**
155  * virtsnd_enable_event_vq() - Enable the event virtqueue.
156  * @snd: VirtIO sound device.
157  *
158  * Context: Any context.
159  */
160 static void virtsnd_enable_event_vq(struct virtio_snd *snd)
161 {
162         struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
163
164         if (!virtqueue_enable_cb(queue->vqueue))
165                 virtsnd_event_notify_cb(queue->vqueue);
166 }
167
168 /**
169  * virtsnd_disable_event_vq() - Disable the event virtqueue.
170  * @snd: VirtIO sound device.
171  *
172  * Context: Any context.
173  */
174 static void virtsnd_disable_event_vq(struct virtio_snd *snd)
175 {
176         struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
177         struct virtio_snd_event *event;
178         u32 length;
179         unsigned long flags;
180
181         if (queue->vqueue) {
182                 spin_lock_irqsave(&queue->lock, flags);
183                 virtqueue_disable_cb(queue->vqueue);
184                 while ((event = virtqueue_get_buf(queue->vqueue, &length)))
185                         virtsnd_event_dispatch(snd, event);
186                 spin_unlock_irqrestore(&queue->lock, flags);
187         }
188 }
189
190 /**
191  * virtsnd_build_devs() - Read configuration and build ALSA devices.
192  * @snd: VirtIO sound device.
193  *
194  * Context: Any context that permits to sleep.
195  * Return: 0 on success, -errno on failure.
196  */
197 static int virtsnd_build_devs(struct virtio_snd *snd)
198 {
199         struct virtio_device *vdev = snd->vdev;
200         struct device *dev = &vdev->dev;
201         int rc;
202
203         rc = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
204                           THIS_MODULE, 0, &snd->card);
205         if (rc < 0)
206                 return rc;
207
208         snd->card->private_data = snd;
209
210         strscpy(snd->card->driver, VIRTIO_SND_CARD_DRIVER,
211                 sizeof(snd->card->driver));
212         strscpy(snd->card->shortname, VIRTIO_SND_CARD_NAME,
213                 sizeof(snd->card->shortname));
214         if (dev->parent->bus)
215                 snprintf(snd->card->longname, sizeof(snd->card->longname),
216                          VIRTIO_SND_CARD_NAME " at %s/%s/%s",
217                          dev->parent->bus->name, dev_name(dev->parent),
218                          dev_name(dev));
219         else
220                 snprintf(snd->card->longname, sizeof(snd->card->longname),
221                          VIRTIO_SND_CARD_NAME " at %s/%s",
222                          dev_name(dev->parent), dev_name(dev));
223
224         rc = virtsnd_jack_parse_cfg(snd);
225         if (rc)
226                 return rc;
227
228         rc = virtsnd_pcm_parse_cfg(snd);
229         if (rc)
230                 return rc;
231
232         rc = virtsnd_chmap_parse_cfg(snd);
233         if (rc)
234                 return rc;
235
236         if (snd->njacks) {
237                 rc = virtsnd_jack_build_devs(snd);
238                 if (rc)
239                         return rc;
240         }
241
242         if (snd->nsubstreams) {
243                 rc = virtsnd_pcm_build_devs(snd);
244                 if (rc)
245                         return rc;
246         }
247
248         if (snd->nchmaps) {
249                 rc = virtsnd_chmap_build_devs(snd);
250                 if (rc)
251                         return rc;
252         }
253
254         return snd_card_register(snd->card);
255 }
256
257 /**
258  * virtsnd_validate() - Validate if the device can be started.
259  * @vdev: VirtIO parent device.
260  *
261  * Context: Any context.
262  * Return: 0 on success, -EINVAL on failure.
263  */
264 static int virtsnd_validate(struct virtio_device *vdev)
265 {
266         if (!vdev->config->get) {
267                 dev_err(&vdev->dev, "configuration access disabled\n");
268                 return -EINVAL;
269         }
270
271         if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
272                 dev_err(&vdev->dev,
273                         "device does not comply with spec version 1.x\n");
274                 return -EINVAL;
275         }
276
277         if (!virtsnd_msg_timeout_ms) {
278                 dev_err(&vdev->dev, "msg_timeout_ms value cannot be zero\n");
279                 return -EINVAL;
280         }
281
282         if (virtsnd_pcm_validate(vdev))
283                 return -EINVAL;
284
285         return 0;
286 }
287
288 /**
289  * virtsnd_probe() - Create and initialize the device.
290  * @vdev: VirtIO parent device.
291  *
292  * Context: Any context that permits to sleep.
293  * Return: 0 on success, -errno on failure.
294  */
295 static int virtsnd_probe(struct virtio_device *vdev)
296 {
297         struct virtio_snd *snd;
298         unsigned int i;
299         int rc;
300
301         snd = devm_kzalloc(&vdev->dev, sizeof(*snd), GFP_KERNEL);
302         if (!snd)
303                 return -ENOMEM;
304
305         snd->vdev = vdev;
306         INIT_LIST_HEAD(&snd->ctl_msgs);
307         INIT_LIST_HEAD(&snd->pcm_list);
308
309         vdev->priv = snd;
310
311         for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i)
312                 spin_lock_init(&snd->queues[i].lock);
313
314         rc = virtsnd_find_vqs(snd);
315         if (rc)
316                 goto on_exit;
317
318         virtio_device_ready(vdev);
319
320         rc = virtsnd_build_devs(snd);
321         if (rc)
322                 goto on_exit;
323
324         virtsnd_enable_event_vq(snd);
325
326 on_exit:
327         if (rc)
328                 virtsnd_remove(vdev);
329
330         return rc;
331 }
332
333 /**
334  * virtsnd_remove() - Remove VirtIO and ALSA devices.
335  * @vdev: VirtIO parent device.
336  *
337  * Context: Any context that permits to sleep.
338  */
339 static void virtsnd_remove(struct virtio_device *vdev)
340 {
341         struct virtio_snd *snd = vdev->priv;
342         unsigned int i;
343
344         virtsnd_disable_event_vq(snd);
345         virtsnd_ctl_msg_cancel_all(snd);
346
347         if (snd->card)
348                 snd_card_free(snd->card);
349
350         vdev->config->del_vqs(vdev);
351         virtio_reset_device(vdev);
352
353         for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
354                 struct virtio_pcm_substream *vss = &snd->substreams[i];
355
356                 cancel_work_sync(&vss->elapsed_period);
357                 virtsnd_pcm_msg_free(vss);
358         }
359
360         kfree(snd->event_msgs);
361 }
362
363 #ifdef CONFIG_PM_SLEEP
364 /**
365  * virtsnd_freeze() - Suspend device.
366  * @vdev: VirtIO parent device.
367  *
368  * Context: Any context.
369  * Return: 0 on success, -errno on failure.
370  */
371 static int virtsnd_freeze(struct virtio_device *vdev)
372 {
373         struct virtio_snd *snd = vdev->priv;
374         unsigned int i;
375
376         virtsnd_disable_event_vq(snd);
377         virtsnd_ctl_msg_cancel_all(snd);
378
379         vdev->config->del_vqs(vdev);
380         virtio_reset_device(vdev);
381
382         for (i = 0; i < snd->nsubstreams; ++i)
383                 cancel_work_sync(&snd->substreams[i].elapsed_period);
384
385         kfree(snd->event_msgs);
386         snd->event_msgs = NULL;
387
388         return 0;
389 }
390
391 /**
392  * virtsnd_restore() - Resume device.
393  * @vdev: VirtIO parent device.
394  *
395  * Context: Any context.
396  * Return: 0 on success, -errno on failure.
397  */
398 static int virtsnd_restore(struct virtio_device *vdev)
399 {
400         struct virtio_snd *snd = vdev->priv;
401         int rc;
402
403         rc = virtsnd_find_vqs(snd);
404         if (rc)
405                 return rc;
406
407         virtio_device_ready(vdev);
408
409         virtsnd_enable_event_vq(snd);
410
411         return 0;
412 }
413 #endif /* CONFIG_PM_SLEEP */
414
415 static const struct virtio_device_id id_table[] = {
416         { VIRTIO_ID_SOUND, VIRTIO_DEV_ANY_ID },
417         { 0 },
418 };
419
420 static struct virtio_driver virtsnd_driver = {
421         .driver.name = KBUILD_MODNAME,
422         .driver.owner = THIS_MODULE,
423         .id_table = id_table,
424         .validate = virtsnd_validate,
425         .probe = virtsnd_probe,
426         .remove = virtsnd_remove,
427 #ifdef CONFIG_PM_SLEEP
428         .freeze = virtsnd_freeze,
429         .restore = virtsnd_restore,
430 #endif
431 };
432
433 module_virtio_driver(virtsnd_driver);
434
435 MODULE_DEVICE_TABLE(virtio, id_table);
436 MODULE_DESCRIPTION("Virtio sound card driver");
437 MODULE_LICENSE("GPL");