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