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