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;
24 struct xen_snd_front_info *front_info = channel->front_info;
28 if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
31 guard(mutex)(&channel->ring_io_lock);
34 rp = channel->u.req.ring.sring->rsp_prod;
43 for (i = channel->u.req.ring.rsp_cons; i != rp; i++) {
44 resp = RING_GET_RESPONSE(&channel->u.req.ring, i);
45 if (resp->id != channel->evt_id)
47 switch (resp->operation) {
53 channel->u.req.resp_status = resp->status;
54 complete(&channel->u.req.completion);
57 channel->u.req.resp_status = resp->status;
58 channel->u.req.resp.hw_param =
59 resp->resp.hw_param;
60 complete(&channel->u.req.completion);
64 dev_err(&front_info->xb_dev->dev,
66 resp->operation);
71 channel->u.req.ring.rsp_cons = i;
72 if (i != channel->u.req.ring.req_prod_pvt) {
75 RING_FINAL_CHECK_FOR_RESPONSES(&channel->u.req.ring,
80 channel->u.req.ring.sring->rsp_event = i + 1;
88 struct xen_snd_front_evtchnl *channel = dev_id;
89 struct xensnd_event_page *page = channel->u.evt.page;
92 if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
95 guard(mutex)(&channel->ring_io_lock);
97 prod = page->in_prod;
100 if (prod == page->in_cons)
108 for (cons = page->in_cons; cons != prod; cons++) {
112 if (unlikely(event->id != channel->evt_id++))
115 switch (event->type) {
117 xen_snd_front_alsa_handle_cur_pos(channel,
118 event->op.cur_pos.position);
123 page->in_cons = cons;
130 void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *channel)
134 channel->u.req.ring.req_prod_pvt++;
135 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->u.req.ring, notify);
137 notify_remote_via_irq(channel->irq);
141 struct xen_snd_front_evtchnl *channel)
145 if (channel->type == EVTCHNL_TYPE_REQ)
146 page = channel->u.req.ring.sring;
147 else if (channel->type == EVTCHNL_TYPE_EVT)
148 page = channel->u.evt.page;
153 channel->state = EVTCHNL_STATE_DISCONNECTED;
154 if (channel->type == EVTCHNL_TYPE_REQ) {
156 channel->u.req.resp_status = -EIO;
157 complete_all(&channel->u.req.completion);
160 if (channel->irq)
161 unbind_from_irqhandler(channel->irq, channel);
163 if (channel->port)
164 xenbus_free_evtchn(front_info->xb_dev, channel->port);
167 xenbus_teardown_ring(&page, 1, &channel->gref);
169 memset(channel, 0, sizeof(*channel));
176 if (!front_info->evt_pairs)
179 for (i = 0; i < front_info->num_evt_pairs; i++) {
180 evtchnl_free(front_info, &front_info->evt_pairs[i].req);
181 evtchnl_free(front_info, &front_info->evt_pairs[i].evt);
184 kfree(front_info->evt_pairs);
185 front_info->evt_pairs = NULL;
189 struct xen_snd_front_evtchnl *channel,
192 struct xenbus_device *xb_dev = front_info->xb_dev;
198 memset(channel, 0, sizeof(*channel));
199 channel->type = type;
200 channel->index = index;
201 channel->front_info = front_info;
202 channel->state = EVTCHNL_STATE_DISCONNECTED;
203 ret = xenbus_setup_ring(xb_dev, GFP_KERNEL, &page, 1, &channel->gref);
207 handler_name = kasprintf(GFP_KERNEL, "%s-%s", XENSND_DRIVER_NAME,
212 ret = -ENOMEM;
216 mutex_init(&channel->ring_io_lock);
221 init_completion(&channel->u.req.completion);
222 mutex_init(&channel->u.req.req_io_lock);
223 XEN_FRONT_RING_INIT(&channel->u.req.ring, sring, XEN_PAGE_SIZE);
227 channel->u.evt.page = page;
231 ret = xenbus_alloc_evtchn(xb_dev, &channel->port);
235 ret = bind_evtchn_to_irq(channel->port);
237 dev_err(&xb_dev->dev,
239 front_info->xb_dev->otherend_id, channel->port, ret);
243 channel->irq = ret;
245 ret = request_threaded_irq(channel->irq, NULL, handler,
246 IRQF_ONESHOT, handler_name, channel);
248 dev_err(&xb_dev->dev, "Failed to request IRQ %d: %d\n",
249 channel->irq, ret);
258 dev_err(&xb_dev->dev, "Failed to allocate ring: %d\n", ret);
265 struct xen_front_cfg_card *cfg = &front_info->cfg;
266 struct device *dev = &front_info->xb_dev->dev;
269 front_info->evt_pairs =
273 if (!front_info->evt_pairs)
274 return -ENOMEM;
277 for (d = 0; d < cfg->num_pcm_instances; d++) {
281 pcm_instance = &cfg->pcm_instances[d];
283 for (s = 0; s < pcm_instance->num_streams_pb; s++) {
284 index = pcm_instance->streams_pb[s].index;
287 &front_info->evt_pairs[index].req,
290 dev_err(dev, "Error allocating control channel\n");
295 &front_info->evt_pairs[index].evt,
298 dev_err(dev, "Error allocating in-event channel\n");
303 for (s = 0; s < pcm_instance->num_streams_cap; s++) {
304 index = pcm_instance->streams_cap[s].index;
307 &front_info->evt_pairs[index].req,
310 dev_err(dev, "Error allocating control channel\n");
315 &front_info->evt_pairs[index].evt,
318 dev_err(dev, "Error allocating in-event channel\n");
324 front_info->num_evt_pairs = num_streams;
333 struct xen_snd_front_evtchnl *channel,
337 struct xenbus_device *xb_dev = channel->front_info->xb_dev;
340 /* Write control channel ring reference. */
341 ret = xenbus_printf(xbt, path, node_ring, "%u", channel->gref);
343 dev_err(&xb_dev->dev, "Error writing ring-ref: %d\n", ret);
347 /* Write event channel ring reference. */
348 ret = xenbus_printf(xbt, path, node_chnl, "%u", channel->port);
350 dev_err(&xb_dev->dev, "Error writing event channel: %d\n", ret);
359 struct xen_front_cfg_card *cfg = &front_info->cfg;
366 xenbus_dev_fatal(front_info->xb_dev, ret,
371 for (d = 0; d < cfg->num_pcm_instances; d++) {
375 pcm_instance = &cfg->pcm_instances[d];
377 for (s = 0; s < pcm_instance->num_streams_pb; s++) {
378 index = pcm_instance->streams_pb[s].index;
381 &front_info->evt_pairs[index].req,
382 pcm_instance->streams_pb[s].xenstore_path,
389 &front_info->evt_pairs[index].evt,
390 pcm_instance->streams_pb[s].xenstore_path,
397 for (s = 0; s < pcm_instance->num_streams_cap; s++) {
398 index = pcm_instance->streams_cap[s].index;
401 &front_info->evt_pairs[index].req,
402 pcm_instance->streams_cap[s].xenstore_path,
409 &front_info->evt_pairs[index].evt,
410 pcm_instance->streams_cap[s].xenstore_path,
419 if (ret == -EAGAIN)
422 xenbus_dev_fatal(front_info->xb_dev, ret,
430 xenbus_dev_fatal(front_info->xb_dev, ret, "writing XenStore");
444 scoped_guard(mutex, &evt_pair->req.ring_io_lock) {
445 evt_pair->req.state = state;
448 scoped_guard(mutex, &evt_pair->evt.ring_io_lock) {
449 evt_pair->evt.state = state;
455 scoped_guard(mutex, &evt_pair->req.ring_io_lock) {
456 evt_pair->req.evt_next_id = 0;
459 scoped_guard(mutex, &evt_pair->evt.ring_io_lock) {
460 evt_pair->evt.evt_next_id = 0;