Lines Matching +full:channel +full:-
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
4 * Xen para-virtual sound device
6 * Copyright (C) 2016-2018 EPAM Systems Inc.
23 struct xen_snd_front_evtchnl *channel = dev_id; in evtchnl_interrupt_req() local
24 struct xen_snd_front_info *front_info = channel->front_info; in evtchnl_interrupt_req()
28 if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED)) in evtchnl_interrupt_req()
31 mutex_lock(&channel->ring_io_lock); in evtchnl_interrupt_req()
34 rp = channel->u.req.ring.sring->rsp_prod; in evtchnl_interrupt_req()
43 for (i = channel->u.req.ring.rsp_cons; i != rp; i++) { in evtchnl_interrupt_req()
44 resp = RING_GET_RESPONSE(&channel->u.req.ring, i); in evtchnl_interrupt_req()
45 if (resp->id != channel->evt_id) in evtchnl_interrupt_req()
47 switch (resp->operation) { in evtchnl_interrupt_req()
53 channel->u.req.resp_status = resp->status; in evtchnl_interrupt_req()
54 complete(&channel->u.req.completion); in evtchnl_interrupt_req()
57 channel->u.req.resp_status = resp->status; in evtchnl_interrupt_req()
58 channel->u.req.resp.hw_param = in evtchnl_interrupt_req()
59 resp->resp.hw_param; in evtchnl_interrupt_req()
60 complete(&channel->u.req.completion); in evtchnl_interrupt_req()
64 dev_err(&front_info->xb_dev->dev, in evtchnl_interrupt_req()
66 resp->operation); in evtchnl_interrupt_req()
71 channel->u.req.ring.rsp_cons = i; in evtchnl_interrupt_req()
72 if (i != channel->u.req.ring.req_prod_pvt) { in evtchnl_interrupt_req()
75 RING_FINAL_CHECK_FOR_RESPONSES(&channel->u.req.ring, in evtchnl_interrupt_req()
80 channel->u.req.ring.sring->rsp_event = i + 1; in evtchnl_interrupt_req()
83 mutex_unlock(&channel->ring_io_lock); in evtchnl_interrupt_req()
89 struct xen_snd_front_evtchnl *channel = dev_id; in evtchnl_interrupt_evt() local
90 struct xensnd_event_page *page = channel->u.evt.page; in evtchnl_interrupt_evt()
93 if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED)) in evtchnl_interrupt_evt()
96 mutex_lock(&channel->ring_io_lock); in evtchnl_interrupt_evt()
98 prod = page->in_prod; in evtchnl_interrupt_evt()
101 if (prod == page->in_cons) in evtchnl_interrupt_evt()
109 for (cons = page->in_cons; cons != prod; cons++) { in evtchnl_interrupt_evt()
113 if (unlikely(event->id != channel->evt_id++)) in evtchnl_interrupt_evt()
116 switch (event->type) { in evtchnl_interrupt_evt()
118 xen_snd_front_alsa_handle_cur_pos(channel, in evtchnl_interrupt_evt()
119 event->op.cur_pos.position); in evtchnl_interrupt_evt()
124 page->in_cons = cons; in evtchnl_interrupt_evt()
129 mutex_unlock(&channel->ring_io_lock); in evtchnl_interrupt_evt()
133 void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *channel) in xen_snd_front_evtchnl_flush() argument
137 channel->u.req.ring.req_prod_pvt++; in xen_snd_front_evtchnl_flush()
138 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->u.req.ring, notify); in xen_snd_front_evtchnl_flush()
140 notify_remote_via_irq(channel->irq); in xen_snd_front_evtchnl_flush()
144 struct xen_snd_front_evtchnl *channel) in evtchnl_free() argument
148 if (channel->type == EVTCHNL_TYPE_REQ) in evtchnl_free()
149 page = channel->u.req.ring.sring; in evtchnl_free()
150 else if (channel->type == EVTCHNL_TYPE_EVT) in evtchnl_free()
151 page = channel->u.evt.page; in evtchnl_free()
156 channel->state = EVTCHNL_STATE_DISCONNECTED; in evtchnl_free()
157 if (channel->type == EVTCHNL_TYPE_REQ) { in evtchnl_free()
159 channel->u.req.resp_status = -EIO; in evtchnl_free()
160 complete_all(&channel->u.req.completion); in evtchnl_free()
163 if (channel->irq) in evtchnl_free()
164 unbind_from_irqhandler(channel->irq, channel); in evtchnl_free()
166 if (channel->port) in evtchnl_free()
167 xenbus_free_evtchn(front_info->xb_dev, channel->port); in evtchnl_free()
170 xenbus_teardown_ring(&page, 1, &channel->gref); in evtchnl_free()
172 memset(channel, 0, sizeof(*channel)); in evtchnl_free()
179 if (!front_info->evt_pairs) in xen_snd_front_evtchnl_free_all()
182 for (i = 0; i < front_info->num_evt_pairs; i++) { in xen_snd_front_evtchnl_free_all()
183 evtchnl_free(front_info, &front_info->evt_pairs[i].req); in xen_snd_front_evtchnl_free_all()
184 evtchnl_free(front_info, &front_info->evt_pairs[i].evt); in xen_snd_front_evtchnl_free_all()
187 kfree(front_info->evt_pairs); in xen_snd_front_evtchnl_free_all()
188 front_info->evt_pairs = NULL; in xen_snd_front_evtchnl_free_all()
192 struct xen_snd_front_evtchnl *channel, in evtchnl_alloc() argument
195 struct xenbus_device *xb_dev = front_info->xb_dev; in evtchnl_alloc()
201 memset(channel, 0, sizeof(*channel)); in evtchnl_alloc()
202 channel->type = type; in evtchnl_alloc()
203 channel->index = index; in evtchnl_alloc()
204 channel->front_info = front_info; in evtchnl_alloc()
205 channel->state = EVTCHNL_STATE_DISCONNECTED; in evtchnl_alloc()
206 ret = xenbus_setup_ring(xb_dev, GFP_KERNEL, &page, 1, &channel->gref); in evtchnl_alloc()
210 handler_name = kasprintf(GFP_KERNEL, "%s-%s", XENSND_DRIVER_NAME, in evtchnl_alloc()
215 ret = -ENOMEM; in evtchnl_alloc()
219 mutex_init(&channel->ring_io_lock); in evtchnl_alloc()
224 init_completion(&channel->u.req.completion); in evtchnl_alloc()
225 mutex_init(&channel->u.req.req_io_lock); in evtchnl_alloc()
226 XEN_FRONT_RING_INIT(&channel->u.req.ring, sring, XEN_PAGE_SIZE); in evtchnl_alloc()
230 channel->u.evt.page = page; in evtchnl_alloc()
234 ret = xenbus_alloc_evtchn(xb_dev, &channel->port); in evtchnl_alloc()
238 ret = bind_evtchn_to_irq(channel->port); in evtchnl_alloc()
240 dev_err(&xb_dev->dev, in evtchnl_alloc()
242 front_info->xb_dev->otherend_id, channel->port, ret); in evtchnl_alloc()
246 channel->irq = ret; in evtchnl_alloc()
248 ret = request_threaded_irq(channel->irq, NULL, handler, in evtchnl_alloc()
249 IRQF_ONESHOT, handler_name, channel); in evtchnl_alloc()
251 dev_err(&xb_dev->dev, "Failed to request IRQ %d: %d\n", in evtchnl_alloc()
252 channel->irq, ret); in evtchnl_alloc()
261 dev_err(&xb_dev->dev, "Failed to allocate ring: %d\n", ret); in evtchnl_alloc()
268 struct xen_front_cfg_card *cfg = &front_info->cfg; in xen_snd_front_evtchnl_create_all()
269 struct device *dev = &front_info->xb_dev->dev; in xen_snd_front_evtchnl_create_all()
272 front_info->evt_pairs = in xen_snd_front_evtchnl_create_all()
276 if (!front_info->evt_pairs) in xen_snd_front_evtchnl_create_all()
277 return -ENOMEM; in xen_snd_front_evtchnl_create_all()
280 for (d = 0; d < cfg->num_pcm_instances; d++) { in xen_snd_front_evtchnl_create_all()
284 pcm_instance = &cfg->pcm_instances[d]; in xen_snd_front_evtchnl_create_all()
286 for (s = 0; s < pcm_instance->num_streams_pb; s++) { in xen_snd_front_evtchnl_create_all()
287 index = pcm_instance->streams_pb[s].index; in xen_snd_front_evtchnl_create_all()
290 &front_info->evt_pairs[index].req, in xen_snd_front_evtchnl_create_all()
293 dev_err(dev, "Error allocating control channel\n"); in xen_snd_front_evtchnl_create_all()
298 &front_info->evt_pairs[index].evt, in xen_snd_front_evtchnl_create_all()
301 dev_err(dev, "Error allocating in-event channel\n"); in xen_snd_front_evtchnl_create_all()
306 for (s = 0; s < pcm_instance->num_streams_cap; s++) { in xen_snd_front_evtchnl_create_all()
307 index = pcm_instance->streams_cap[s].index; in xen_snd_front_evtchnl_create_all()
310 &front_info->evt_pairs[index].req, in xen_snd_front_evtchnl_create_all()
313 dev_err(dev, "Error allocating control channel\n"); in xen_snd_front_evtchnl_create_all()
318 &front_info->evt_pairs[index].evt, in xen_snd_front_evtchnl_create_all()
321 dev_err(dev, "Error allocating in-event channel\n"); in xen_snd_front_evtchnl_create_all()
327 front_info->num_evt_pairs = num_streams; in xen_snd_front_evtchnl_create_all()
336 struct xen_snd_front_evtchnl *channel, in evtchnl_publish() argument
340 struct xenbus_device *xb_dev = channel->front_info->xb_dev; in evtchnl_publish()
343 /* Write control channel ring reference. */ in evtchnl_publish()
344 ret = xenbus_printf(xbt, path, node_ring, "%u", channel->gref); in evtchnl_publish()
346 dev_err(&xb_dev->dev, "Error writing ring-ref: %d\n", ret); in evtchnl_publish()
350 /* Write event channel ring reference. */ in evtchnl_publish()
351 ret = xenbus_printf(xbt, path, node_chnl, "%u", channel->port); in evtchnl_publish()
353 dev_err(&xb_dev->dev, "Error writing event channel: %d\n", ret); in evtchnl_publish()
362 struct xen_front_cfg_card *cfg = &front_info->cfg; in xen_snd_front_evtchnl_publish_all()
369 xenbus_dev_fatal(front_info->xb_dev, ret, in xen_snd_front_evtchnl_publish_all()
374 for (d = 0; d < cfg->num_pcm_instances; d++) { in xen_snd_front_evtchnl_publish_all()
378 pcm_instance = &cfg->pcm_instances[d]; in xen_snd_front_evtchnl_publish_all()
380 for (s = 0; s < pcm_instance->num_streams_pb; s++) { in xen_snd_front_evtchnl_publish_all()
381 index = pcm_instance->streams_pb[s].index; in xen_snd_front_evtchnl_publish_all()
384 &front_info->evt_pairs[index].req, in xen_snd_front_evtchnl_publish_all()
385 pcm_instance->streams_pb[s].xenstore_path, in xen_snd_front_evtchnl_publish_all()
392 &front_info->evt_pairs[index].evt, in xen_snd_front_evtchnl_publish_all()
393 pcm_instance->streams_pb[s].xenstore_path, in xen_snd_front_evtchnl_publish_all()
400 for (s = 0; s < pcm_instance->num_streams_cap; s++) { in xen_snd_front_evtchnl_publish_all()
401 index = pcm_instance->streams_cap[s].index; in xen_snd_front_evtchnl_publish_all()
404 &front_info->evt_pairs[index].req, in xen_snd_front_evtchnl_publish_all()
405 pcm_instance->streams_cap[s].xenstore_path, in xen_snd_front_evtchnl_publish_all()
412 &front_info->evt_pairs[index].evt, in xen_snd_front_evtchnl_publish_all()
413 pcm_instance->streams_cap[s].xenstore_path, in xen_snd_front_evtchnl_publish_all()
422 if (ret == -EAGAIN) in xen_snd_front_evtchnl_publish_all()
425 xenbus_dev_fatal(front_info->xb_dev, ret, in xen_snd_front_evtchnl_publish_all()
433 xenbus_dev_fatal(front_info->xb_dev, ret, "writing XenStore"); in xen_snd_front_evtchnl_publish_all()
447 mutex_lock(&evt_pair->req.ring_io_lock); in xen_snd_front_evtchnl_pair_set_connected()
448 evt_pair->req.state = state; in xen_snd_front_evtchnl_pair_set_connected()
449 mutex_unlock(&evt_pair->req.ring_io_lock); in xen_snd_front_evtchnl_pair_set_connected()
451 mutex_lock(&evt_pair->evt.ring_io_lock); in xen_snd_front_evtchnl_pair_set_connected()
452 evt_pair->evt.state = state; in xen_snd_front_evtchnl_pair_set_connected()
453 mutex_unlock(&evt_pair->evt.ring_io_lock); in xen_snd_front_evtchnl_pair_set_connected()
458 mutex_lock(&evt_pair->req.ring_io_lock); in xen_snd_front_evtchnl_pair_clear()
459 evt_pair->req.evt_next_id = 0; in xen_snd_front_evtchnl_pair_clear()
460 mutex_unlock(&evt_pair->req.ring_io_lock); in xen_snd_front_evtchnl_pair_clear()
462 mutex_lock(&evt_pair->evt.ring_io_lock); in xen_snd_front_evtchnl_pair_clear()
463 evt_pair->evt.evt_next_id = 0; in xen_snd_front_evtchnl_pair_clear()
464 mutex_unlock(&evt_pair->evt.ring_io_lock); in xen_snd_front_evtchnl_pair_clear()