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 case VIRTIO_SND_EVT_CTL_NOTIFY: 68 virtsnd_kctl_event(snd, event); 69 break; 70 } 71 } 72 73 /** 74 * virtsnd_event_notify_cb() - Dispatch all reported events from the event queue. 75 * @vqueue: Underlying event virtqueue. 76 * 77 * This callback function is called upon a vring interrupt request from the 78 * device. 79 * 80 * Context: Interrupt context. 81 */ 82 static void virtsnd_event_notify_cb(struct virtqueue *vqueue) 83 { 84 struct virtio_snd *snd = vqueue->vdev->priv; 85 struct virtio_snd_queue *queue = virtsnd_event_queue(snd); 86 struct virtio_snd_event *event; 87 u32 length; 88 unsigned long flags; 89 90 spin_lock_irqsave(&queue->lock, flags); 91 do { 92 virtqueue_disable_cb(vqueue); 93 while ((event = virtqueue_get_buf(vqueue, &length))) { 94 virtsnd_event_dispatch(snd, event); 95 virtsnd_event_send(vqueue, event, true, GFP_ATOMIC); 96 } 97 } while (!virtqueue_enable_cb(vqueue)); 98 spin_unlock_irqrestore(&queue->lock, flags); 99 } 100 101 /** 102 * virtsnd_find_vqs() - Enumerate and initialize all virtqueues. 103 * @snd: VirtIO sound device. 104 * 105 * After calling this function, the event queue is disabled. 106 * 107 * Context: Any context. 108 * Return: 0 on success, -errno on failure. 109 */ 110 static int virtsnd_find_vqs(struct virtio_snd *snd) 111 { 112 struct virtio_device *vdev = snd->vdev; 113 static vq_callback_t *callbacks[VIRTIO_SND_VQ_MAX] = { 114 [VIRTIO_SND_VQ_CONTROL] = virtsnd_ctl_notify_cb, 115 [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb, 116 [VIRTIO_SND_VQ_TX] = virtsnd_pcm_tx_notify_cb, 117 [VIRTIO_SND_VQ_RX] = virtsnd_pcm_rx_notify_cb 118 }; 119 static const char *names[VIRTIO_SND_VQ_MAX] = { 120 [VIRTIO_SND_VQ_CONTROL] = "virtsnd-ctl", 121 [VIRTIO_SND_VQ_EVENT] = "virtsnd-event", 122 [VIRTIO_SND_VQ_TX] = "virtsnd-tx", 123 [VIRTIO_SND_VQ_RX] = "virtsnd-rx" 124 }; 125 struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 }; 126 unsigned int i; 127 unsigned int n; 128 int rc; 129 130 rc = virtio_find_vqs(vdev, VIRTIO_SND_VQ_MAX, vqs, callbacks, names, 131 NULL); 132 if (rc) { 133 dev_err(&vdev->dev, "failed to initialize virtqueues\n"); 134 return rc; 135 } 136 137 for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i) 138 snd->queues[i].vqueue = vqs[i]; 139 140 /* Allocate events and populate the event queue */ 141 virtqueue_disable_cb(vqs[VIRTIO_SND_VQ_EVENT]); 142 143 n = virtqueue_get_vring_size(vqs[VIRTIO_SND_VQ_EVENT]); 144 145 snd->event_msgs = kmalloc_array(n, sizeof(*snd->event_msgs), 146 GFP_KERNEL); 147 if (!snd->event_msgs) 148 return -ENOMEM; 149 150 for (i = 0; i < n; ++i) 151 virtsnd_event_send(vqs[VIRTIO_SND_VQ_EVENT], 152 &snd->event_msgs[i], false, GFP_KERNEL); 153 154 return 0; 155 } 156 157 /** 158 * virtsnd_enable_event_vq() - Enable the event virtqueue. 159 * @snd: VirtIO sound device. 160 * 161 * Context: Any context. 162 */ 163 static void virtsnd_enable_event_vq(struct virtio_snd *snd) 164 { 165 struct virtio_snd_queue *queue = virtsnd_event_queue(snd); 166 167 if (!virtqueue_enable_cb(queue->vqueue)) 168 virtsnd_event_notify_cb(queue->vqueue); 169 } 170 171 /** 172 * virtsnd_disable_event_vq() - Disable the event virtqueue. 173 * @snd: VirtIO sound device. 174 * 175 * Context: Any context. 176 */ 177 static void virtsnd_disable_event_vq(struct virtio_snd *snd) 178 { 179 struct virtio_snd_queue *queue = virtsnd_event_queue(snd); 180 struct virtio_snd_event *event; 181 u32 length; 182 unsigned long flags; 183 184 if (queue->vqueue) { 185 spin_lock_irqsave(&queue->lock, flags); 186 virtqueue_disable_cb(queue->vqueue); 187 while ((event = virtqueue_get_buf(queue->vqueue, &length))) 188 virtsnd_event_dispatch(snd, event); 189 spin_unlock_irqrestore(&queue->lock, flags); 190 } 191 } 192 193 /** 194 * virtsnd_build_devs() - Read configuration and build ALSA devices. 195 * @snd: VirtIO sound device. 196 * 197 * Context: Any context that permits to sleep. 198 * Return: 0 on success, -errno on failure. 199 */ 200 static int virtsnd_build_devs(struct virtio_snd *snd) 201 { 202 struct virtio_device *vdev = snd->vdev; 203 struct device *dev = &vdev->dev; 204 int rc; 205 206 rc = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 207 THIS_MODULE, 0, &snd->card); 208 if (rc < 0) 209 return rc; 210 211 snd->card->private_data = snd; 212 213 strscpy(snd->card->driver, VIRTIO_SND_CARD_DRIVER, 214 sizeof(snd->card->driver)); 215 strscpy(snd->card->shortname, VIRTIO_SND_CARD_NAME, 216 sizeof(snd->card->shortname)); 217 if (dev->parent->bus) 218 snprintf(snd->card->longname, sizeof(snd->card->longname), 219 VIRTIO_SND_CARD_NAME " at %s/%s/%s", 220 dev->parent->bus->name, dev_name(dev->parent), 221 dev_name(dev)); 222 else 223 snprintf(snd->card->longname, sizeof(snd->card->longname), 224 VIRTIO_SND_CARD_NAME " at %s/%s", 225 dev_name(dev->parent), dev_name(dev)); 226 227 rc = virtsnd_jack_parse_cfg(snd); 228 if (rc) 229 return rc; 230 231 rc = virtsnd_pcm_parse_cfg(snd); 232 if (rc) 233 return rc; 234 235 rc = virtsnd_chmap_parse_cfg(snd); 236 if (rc) 237 return rc; 238 239 if (virtio_has_feature(vdev, VIRTIO_SND_F_CTLS)) { 240 rc = virtsnd_kctl_parse_cfg(snd); 241 if (rc) 242 return rc; 243 } 244 245 if (snd->njacks) { 246 rc = virtsnd_jack_build_devs(snd); 247 if (rc) 248 return rc; 249 } 250 251 if (snd->nsubstreams) { 252 rc = virtsnd_pcm_build_devs(snd); 253 if (rc) 254 return rc; 255 } 256 257 if (snd->nchmaps) { 258 rc = virtsnd_chmap_build_devs(snd); 259 if (rc) 260 return rc; 261 } 262 263 if (snd->nkctls) { 264 rc = virtsnd_kctl_build_devs(snd); 265 if (rc) 266 return rc; 267 } 268 269 return snd_card_register(snd->card); 270 } 271 272 /** 273 * virtsnd_validate() - Validate if the device can be started. 274 * @vdev: VirtIO parent device. 275 * 276 * Context: Any context. 277 * Return: 0 on success, -EINVAL on failure. 278 */ 279 static int virtsnd_validate(struct virtio_device *vdev) 280 { 281 if (!vdev->config->get) { 282 dev_err(&vdev->dev, "configuration access disabled\n"); 283 return -EINVAL; 284 } 285 286 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) { 287 dev_err(&vdev->dev, 288 "device does not comply with spec version 1.x\n"); 289 return -EINVAL; 290 } 291 292 if (!virtsnd_msg_timeout_ms) { 293 dev_err(&vdev->dev, "msg_timeout_ms value cannot be zero\n"); 294 return -EINVAL; 295 } 296 297 if (virtsnd_pcm_validate(vdev)) 298 return -EINVAL; 299 300 return 0; 301 } 302 303 /** 304 * virtsnd_probe() - Create and initialize the device. 305 * @vdev: VirtIO parent device. 306 * 307 * Context: Any context that permits to sleep. 308 * Return: 0 on success, -errno on failure. 309 */ 310 static int virtsnd_probe(struct virtio_device *vdev) 311 { 312 struct virtio_snd *snd; 313 unsigned int i; 314 int rc; 315 316 snd = devm_kzalloc(&vdev->dev, sizeof(*snd), GFP_KERNEL); 317 if (!snd) 318 return -ENOMEM; 319 320 snd->vdev = vdev; 321 INIT_LIST_HEAD(&snd->ctl_msgs); 322 INIT_LIST_HEAD(&snd->pcm_list); 323 324 vdev->priv = snd; 325 326 for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i) 327 spin_lock_init(&snd->queues[i].lock); 328 329 rc = virtsnd_find_vqs(snd); 330 if (rc) 331 goto on_exit; 332 333 virtio_device_ready(vdev); 334 335 rc = virtsnd_build_devs(snd); 336 if (rc) 337 goto on_exit; 338 339 virtsnd_enable_event_vq(snd); 340 341 on_exit: 342 if (rc) 343 virtsnd_remove(vdev); 344 345 return rc; 346 } 347 348 /** 349 * virtsnd_remove() - Remove VirtIO and ALSA devices. 350 * @vdev: VirtIO parent device. 351 * 352 * Context: Any context that permits to sleep. 353 */ 354 static void virtsnd_remove(struct virtio_device *vdev) 355 { 356 struct virtio_snd *snd = vdev->priv; 357 unsigned int i; 358 359 virtsnd_disable_event_vq(snd); 360 virtsnd_ctl_msg_cancel_all(snd); 361 362 if (snd->card) 363 snd_card_free(snd->card); 364 365 vdev->config->del_vqs(vdev); 366 virtio_reset_device(vdev); 367 368 for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) { 369 struct virtio_pcm_substream *vss = &snd->substreams[i]; 370 371 cancel_work_sync(&vss->elapsed_period); 372 virtsnd_pcm_msg_free(vss); 373 } 374 375 kfree(snd->event_msgs); 376 } 377 378 #ifdef CONFIG_PM_SLEEP 379 /** 380 * virtsnd_freeze() - Suspend device. 381 * @vdev: VirtIO parent device. 382 * 383 * Context: Any context. 384 * Return: 0 on success, -errno on failure. 385 */ 386 static int virtsnd_freeze(struct virtio_device *vdev) 387 { 388 struct virtio_snd *snd = vdev->priv; 389 unsigned int i; 390 391 virtsnd_disable_event_vq(snd); 392 virtsnd_ctl_msg_cancel_all(snd); 393 394 vdev->config->del_vqs(vdev); 395 virtio_reset_device(vdev); 396 397 for (i = 0; i < snd->nsubstreams; ++i) 398 cancel_work_sync(&snd->substreams[i].elapsed_period); 399 400 kfree(snd->event_msgs); 401 snd->event_msgs = NULL; 402 403 return 0; 404 } 405 406 /** 407 * virtsnd_restore() - Resume device. 408 * @vdev: VirtIO parent device. 409 * 410 * Context: Any context. 411 * Return: 0 on success, -errno on failure. 412 */ 413 static int virtsnd_restore(struct virtio_device *vdev) 414 { 415 struct virtio_snd *snd = vdev->priv; 416 int rc; 417 418 rc = virtsnd_find_vqs(snd); 419 if (rc) 420 return rc; 421 422 virtio_device_ready(vdev); 423 424 virtsnd_enable_event_vq(snd); 425 426 return 0; 427 } 428 #endif /* CONFIG_PM_SLEEP */ 429 430 static const struct virtio_device_id id_table[] = { 431 { VIRTIO_ID_SOUND, VIRTIO_DEV_ANY_ID }, 432 { 0 }, 433 }; 434 435 static unsigned int features[] = { 436 VIRTIO_SND_F_CTLS 437 }; 438 439 static struct virtio_driver virtsnd_driver = { 440 .driver.name = KBUILD_MODNAME, 441 .id_table = id_table, 442 .feature_table = features, 443 .feature_table_size = ARRAY_SIZE(features), 444 .validate = virtsnd_validate, 445 .probe = virtsnd_probe, 446 .remove = virtsnd_remove, 447 #ifdef CONFIG_PM_SLEEP 448 .freeze = virtsnd_freeze, 449 .restore = virtsnd_restore, 450 #endif 451 }; 452 453 module_virtio_driver(virtsnd_driver); 454 455 MODULE_DEVICE_TABLE(virtio, id_table); 456 MODULE_DESCRIPTION("Virtio sound card driver"); 457 MODULE_LICENSE("GPL"); 458