Exemple #1
0
Fichier : init.c Projet : Fantu/Xen
static int init_evt_srv(struct libxenvchan *ctrl, int domain, xentoollog_logger *logger)
{
	evtchn_port_or_error_t port;

	ctrl->event = xc_evtchn_open(logger, 0);
	if (!ctrl->event)
		return -1;

	port = xc_evtchn_bind_unbound_port(ctrl->event, domain);
	if (port < 0)
		goto fail;
	ctrl->event_port = port;

	if (xc_evtchn_unmask(ctrl->event, ctrl->event_port))
		goto fail;

	return 0;

fail:
	if (port >= 0)
		xc_evtchn_unbind(ctrl->event, port);

	xc_evtchn_close(ctrl->event);
	ctrl->event = NULL;

	return -1;
}
CAMLprim value stub_eventchn_bind_unbound_port(value xce, value remote_domid)
{
  evtchn_port_or_error_t rc;

  rc = xc_evtchn_bind_unbound_port(_H(xce), Int_val(remote_domid));
  if (rc == -1)
    caml_failwith("evtchn bind_unbound_port failed");

  return Val_int(rc);

}
CAMLprim value stub_eventchn_bind_unbound_port(value xce, value remote_domid)
{
  CAMLparam2(xce, remote_domid);
  evtchn_port_or_error_t rc;

  rc = xc_evtchn_bind_unbound_port(_H(xce), Int_val(remote_domid));
  if (rc == -1)
    {
      perror("xc_evtchn_bind_unbound_port");
      caml_failwith(strerror(errno));
    }

  CAMLreturn(Val_int(rc));

}
Exemple #4
0
ivc_connection_t *acceptConnection(libIVC_t *iface,
                                   char *name,
                                   ivc_contype_t type,
                                   uint32_t num_pages,
                                   float per)
{
  char *key, *val, *domStr = NULL;
  uint32_t me, other, *gs, ps;
  unsigned int len;
  void *buffer;

  /* we can only do this if we create grant references */
  if(!iface->gs) return NULL;
  /* other <- read `fmap` waitForKey xs (targetPath ++ "/LeftDomId) */
  ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name);
  while(!domStr) { domStr = xs_read(iface->xs, 0, key, &len); }
  sscanf(domStr, "dom%d", &other);
  /* me <- xsGetDomId */
  me = getMyDomId(iface);
  /* (gs, ps, confirm) <- makeConnection other extra */
  gs = calloc(num_pages, sizeof(uint32_t));
  buffer = xc_gntshr_share_pages(iface->gs, other, num_pages, gs, 1);
  assert(buffer);
  ps = xc_evtchn_bind_unbound_port(iface->ec, other);
  assert(ps);
  /* xsWrite xs (targetPath ++ "/RightDomId") (show me) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name);
  free(val), ASPRINTF(&val, "dom%d", me);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightGrantRefs") (show gs) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name);
  free(val), val = showGrantRefList(gs, num_pages);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightPorts") (show ps) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name);
  free(val), ASPRINTF(&val, "[echan:%d]", ps);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* _ <- waitForKey xs (targetPath ++ "/LeftConnectionConfirmed") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name);
  free(val), val = NULL;
  while(!val) { val = xs_read(iface->xs, 0, key, &len); }
  /* removePath xs targetPath */
  free(key), ASPRINTF(&key, "/rendezvous/%s", name);
  xs_rm(iface->xs, 0, key);
  /* confirm */
  return buildChannel(iface, other, type, ps, buffer, 4096 * num_pages, per, 1);
}
int pa__init(pa_module*m) {

    struct userdata *u;
    pa_modargs *ma;
    pa_sink_new_data data;
    int backend_state;
    int ret;
    char strbuf[100];

    pa_assert(m);

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("Failed to parse module arguments.");
        goto fail;
    }

    ss = m->core->default_sample_spec;
    map = m->core->default_channel_map;

    /* user arguments override these */
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
        pa_log("Invalid sample format specification or channel map");
        return 1;
    }

    /* Xen Basic init */
    xsh = xs_domain_open();
    if (xsh==NULL) {
        pa_log("xs_domain_open failed");
        goto fail;
    }
    set_state(XenbusStateUnknown);

    xch = xc_interface_open(NULL, NULL, 0);
    if (xch==0) {
        pa_log("xc_interface_open failed");
        goto fail;
    }

    xce = xc_evtchn_open(NULL, 0);
    if (xce==0) {
        pa_log("xc_evtchn_open failed");
        goto fail;
    }

    /* use only dom0 as the backend for now */
    xen_evtchn_port = xc_evtchn_bind_unbound_port(xce, 0);
    if (xen_evtchn_port == 0) {
        pa_log("xc_evtchn_bind_unbound_port failed");
    }

    /* get grant reference & map locally */
    if (alloc_gref(&gref, (void**)&ioring)) {
       pa_log("alloc_gref failed");
    };
    device_id = 0; /* hardcoded for now */

    if (register_backend_state_watch()) {
        pa_log("Xen sink: register xenstore watch failed");
    };

    publish_param_int("event-channel", xen_evtchn_port);
    publish_param_int("ring-ref", gref.gref_ids[0]);

    /* let's ask for something absurd and deal with rejection */
    ss.rate = 192000;

    publish_spec(&ss);

    ret=0;
    while (!ret) {
        backend_state = wait_for_backend_state_change();
        if (backend_state == STATE_UNDEFINED) {
            pa_log("Xen Backend is taking long to respond, still waiting...");
            continue;
        } else if (backend_state == -1) {
            pa_log("Error while waiting for backend: %s", strerror(errno));
            break;
            goto fail;
        }
        ret = state_callbacks[backend_state]();
    }
    if (ret!=NEGOTIATION_OK) {
        pa_log("Negotiation with Xen backend failed!");
        return 1;
    }

    pa_sample_spec_snprint(strbuf, 100, &ss);
    pa_log_debug("Negotiation ended, the result was: %s", strbuf);

    /* End of Phase 2, begin playback cycle */

    u = pa_xnew0(struct userdata, 1);
    u->core = m->core;
    u->module = m;
    m->userdata = u;
    pa_memchunk_reset(&u->memchunk);
    u->rtpoll = pa_rtpoll_new();
    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
    u->write_type = 0;

    /* init ring buffer */
    ioring->prod_indx = ioring->cons_indx = 0;
    ioring->usable_buffer_space = BUFSIZE - BUFSIZE % pa_frame_size(&ss);

    pa_sink_new_data_init(&data);
    data.driver = __FILE__;
    data.module = m;
    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, "xensink");
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Xen PV audio sink");
    pa_sink_new_data_set_sample_spec(&data, &ss);
    pa_sink_new_data_set_channel_map(&data, &map);

    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
        pa_log("Invalid properties");
        pa_sink_new_data_done(&data);
        goto fail;
    }

    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
    pa_sink_new_data_done(&data);

    if (!u->sink) {
        pa_log("Failed to create sink.");
        goto fail;
    }

    u->sink->parent.process_msg = sink_process_msg;
    u->sink->userdata = u;

    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
    pa_sink_set_rtpoll(u->sink, u->rtpoll);
    pa_sink_set_max_request(u->sink, ioring->usable_buffer_space);
    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(ioring->usable_buffer_space, &u->sink->sample_spec));

    u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);

    if (!(u->thread = pa_thread_new("xenpv-sink", thread_func, u))) {
        pa_log("Failed to create thread.");
        goto fail;
    }

    pa_sink_put(u->sink);

    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    pa__done(m);

    return -1;
}