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 struct virtqueue_info vqs_info[VIRTIO_SND_VQ_MAX] = { 114 [VIRTIO_SND_VQ_CONTROL] = { "virtsnd-ctl", 115 virtsnd_ctl_notify_cb }, 116 [VIRTIO_SND_VQ_EVENT] = { "virtsnd-event", 117 virtsnd_event_notify_cb }, 118 [VIRTIO_SND_VQ_TX] = { "virtsnd-tx", 119 virtsnd_pcm_tx_notify_cb }, 120 [VIRTIO_SND_VQ_RX] = { "virtsnd-rx", 121 virtsnd_pcm_rx_notify_cb }, 122 }; 123 struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 }; 124 unsigned int i; 125 unsigned int n; 126 int rc; 127 128 rc = virtio_find_vqs(vdev, VIRTIO_SND_VQ_MAX, vqs, vqs_info, 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 (virtio_has_feature(vdev, VIRTIO_SND_F_CTLS)) { 237 rc = virtsnd_kctl_parse_cfg(snd); 238 if (rc) 239 return rc; 240 } 241 242 if (snd->njacks) { 243 rc = virtsnd_jack_build_devs(snd); 244 if (rc) 245 return rc; 246 } 247 248 if (snd->nsubstreams) { 249 rc = virtsnd_pcm_build_devs(snd); 250 if (rc) 251 return rc; 252 } 253 254 if (snd->nchmaps) { 255 rc = virtsnd_chmap_build_devs(snd); 256 if (rc) 257 return rc; 258 } 259 260 if (snd->nkctls) { 261 rc = virtsnd_kctl_build_devs(snd); 262 if (rc) 263 return rc; 264 } 265 266 return snd_card_register(snd->card); 267 } 268 269 /** 270 * virtsnd_validate() - Validate if the device can be started. 271 * @vdev: VirtIO parent device. 272 * 273 * Context: Any context. 274 * Return: 0 on success, -EINVAL on failure. 275 */ 276 static int virtsnd_validate(struct virtio_device *vdev) 277 { 278 if (!vdev->config->get) { 279 dev_err(&vdev->dev, "configuration access disabled\n"); 280 return -EINVAL; 281 } 282 283 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) { 284 dev_err(&vdev->dev, 285 "device does not comply with spec version 1.x\n"); 286 return -EINVAL; 287 } 288 289 if (!virtsnd_msg_timeout_ms) { 290 dev_err(&vdev->dev, "msg_timeout_ms value cannot be zero\n"); 291 return -EINVAL; 292 } 293 294 if (virtsnd_pcm_validate(vdev)) 295 return -EINVAL; 296 297 return 0; 298 } 299 300 /** 301 * virtsnd_probe() - Create and initialize the device. 302 * @vdev: VirtIO parent device. 303 * 304 * Context: Any context that permits to sleep. 305 * Return: 0 on success, -errno on failure. 306 */ 307 static int virtsnd_probe(struct virtio_device *vdev) 308 { 309 struct virtio_snd *snd; 310 unsigned int i; 311 int rc; 312 313 snd = devm_kzalloc(&vdev->dev, sizeof(*snd), GFP_KERNEL); 314 if (!snd) 315 return -ENOMEM; 316 317 snd->vdev = vdev; 318 INIT_LIST_HEAD(&snd->ctl_msgs); 319 INIT_LIST_HEAD(&snd->pcm_list); 320 321 vdev->priv = snd; 322 323 for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i) 324 spin_lock_init(&snd->queues[i].lock); 325 326 rc = virtsnd_find_vqs(snd); 327 if (rc) 328 goto on_exit; 329 330 virtio_device_ready(vdev); 331 332 rc = virtsnd_build_devs(snd); 333 if (rc) 334 goto on_exit; 335 336 virtsnd_enable_event_vq(snd); 337 338 on_exit: 339 if (rc) 340 virtsnd_remove(vdev); 341 342 return rc; 343 } 344 345 /** 346 * virtsnd_remove() - Remove VirtIO and ALSA devices. 347 * @vdev: VirtIO parent device. 348 * 349 * Context: Any context that permits to sleep. 350 */ 351 static void virtsnd_remove(struct virtio_device *vdev) 352 { 353 struct virtio_snd *snd = vdev->priv; 354 unsigned int i; 355 356 virtsnd_disable_event_vq(snd); 357 virtsnd_ctl_msg_cancel_all(snd); 358 359 if (snd->card) 360 snd_card_free(snd->card); 361 362 vdev->config->del_vqs(vdev); 363 virtio_reset_device(vdev); 364 365 for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) { 366 struct virtio_pcm_substream *vss = &snd->substreams[i]; 367 368 cancel_work_sync(&vss->elapsed_period); 369 virtsnd_pcm_msg_free(vss); 370 } 371 372 kfree(snd->event_msgs); 373 } 374 375 #ifdef CONFIG_PM_SLEEP 376 /** 377 * virtsnd_freeze() - Suspend device. 378 * @vdev: VirtIO parent device. 379 * 380 * Context: Any context. 381 * Return: 0 on success, -errno on failure. 382 */ 383 static int virtsnd_freeze(struct virtio_device *vdev) 384 { 385 struct virtio_snd *snd = vdev->priv; 386 unsigned int i; 387 388 virtsnd_disable_event_vq(snd); 389 virtsnd_ctl_msg_cancel_all(snd); 390 391 vdev->config->del_vqs(vdev); 392 virtio_reset_device(vdev); 393 394 for (i = 0; i < snd->nsubstreams; ++i) 395 cancel_work_sync(&snd->substreams[i].elapsed_period); 396 397 kfree(snd->event_msgs); 398 snd->event_msgs = NULL; 399 400 return 0; 401 } 402 403 /** 404 * virtsnd_restore() - Resume device. 405 * @vdev: VirtIO parent device. 406 * 407 * Context: Any context. 408 * Return: 0 on success, -errno on failure. 409 */ 410 static int virtsnd_restore(struct virtio_device *vdev) 411 { 412 struct virtio_snd *snd = vdev->priv; 413 int rc; 414 415 rc = virtsnd_find_vqs(snd); 416 if (rc) 417 return rc; 418 419 virtio_device_ready(vdev); 420 421 virtsnd_enable_event_vq(snd); 422 423 return 0; 424 } 425 #endif /* CONFIG_PM_SLEEP */ 426 427 static const struct virtio_device_id id_table[] = { 428 { VIRTIO_ID_SOUND, VIRTIO_DEV_ANY_ID }, 429 { 0 }, 430 }; 431 432 static unsigned int features[] = { 433 VIRTIO_SND_F_CTLS 434 }; 435 436 static struct virtio_driver virtsnd_driver = { 437 .driver.name = KBUILD_MODNAME, 438 .id_table = id_table, 439 .feature_table = features, 440 .feature_table_size = ARRAY_SIZE(features), 441 .validate = virtsnd_validate, 442 .probe = virtsnd_probe, 443 .remove = virtsnd_remove, 444 #ifdef CONFIG_PM_SLEEP 445 .freeze = virtsnd_freeze, 446 .restore = virtsnd_restore, 447 #endif 448 }; 449 450 module_virtio_driver(virtsnd_driver); 451 452 MODULE_DEVICE_TABLE(virtio, id_table); 453 MODULE_DESCRIPTION("Virtio sound card driver"); 454 MODULE_LICENSE("GPL"); 455