static errval_t move_to_root(struct capref src, struct capref *dest) #endif { errval_t err; err = slot_alloc_root(dest); if (err_is_fail(err)) { return err_push(err, LIB_ERR_SLOT_ALLOC); } err = cap_copy(*dest, src); if (err_is_fail(err)) { return err_push(err, LIB_ERR_CAP_COPY); } err = cap_delete(src); if (err_is_fail(err)) { return err_push(err, LIB_ERR_WHILE_DELETING); } err = slot_free(src); if (err_is_fail(err)) { return err_push(err, LIB_ERR_WHILE_FREEING_SLOT); } return SYS_ERR_OK; }
/** * Act upon request to create a driver instance. * * \param binding Controller binding * \param cls What class to instantiate? * \param cls_len Ignored. * \param name What name the driver instance should have. * \param nlen Ignored. * \param cap Capabilities for the driver instance. * \param flags Flags for the driver instance. */ static void create_handler(struct ddomain_binding* binding, const char* cls, size_t cls_len, const char* name, size_t nlen, const char* a1, size_t a1len, const char* a2, size_t a2len, const char* a3, size_t a3len, const char* a4, size_t a4len, struct capref cap1, struct capref cap2, struct capref cap3, struct capref cap4, struct capref cap5, struct capref cap6, uint64_t flags) { errval_t err; DRIVERKIT_DEBUG("Driver domain got create message from kaluga for cls=%s," "name=%s\n", cls, name); iref_t dev = 0, ctrl = 0; static size_t NR_CAPS = 6; static size_t NR_ARGS = 4; // This array is owned by the driver after create: struct capref* cap_array = calloc(sizeof(struct capref), NR_CAPS); cap_array[0] = cap1; cap_array[1] = cap2; cap_array[2] = cap3; cap_array[3] = cap4; cap_array[4] = cap5; cap_array[5] = cap6; struct capref cnodecap; err = slot_alloc_root(&cnodecap); assert(err_is_ok(err)); err = cap_copy(cnodecap, cap_array[0]); struct capref cap0_0 = { .slot = 0, .cnode = build_cnoderef(cnodecap, CNODE_TYPE_OTHER) }; char debug_msg[100]; debug_print_cap_at_capref(debug_msg, sizeof(debug_msg), cap0_0); DRIVERKIT_DEBUG("Received cap0_0=%s\n", debug_msg); char** args_array = calloc(sizeof(char*), 4); args_array[0] = arg_valid(a1) ? strdup(a1) : NULL; args_array[1] = arg_valid(a2) ? strdup(a2) : NULL; args_array[2] = arg_valid(a3) ? strdup(a3) : NULL; args_array[3] = arg_valid(a4) ? strdup(a4) : NULL; int args_len; for(args_len=0; args_len<NR_ARGS; args_len++) { if(args_array[args_len] == NULL) break; } DRIVERKIT_DEBUG("Instantiate driver\n"); err = driverkit_create_driver(cls, name, cap_array, NR_CAPS, args_array, args_len, flags, &dev, &ctrl); if (err_is_fail(err)) { DEBUG_ERR(err, "Instantiating driver failed, report this back to Kaluga." "name=%s, cls=%s\n", name, cls); } DRIVERKIT_DEBUG("sending create response to kaluga\n"); err = ddomain_create_response__tx(binding, NOP_CONT, dev, ctrl, err); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Sending reply failed.\n"); } } /** * Destroy an existing driver instance. * * \param binding Controller binding. * \param name Name of the driver instance. * \param len Ignored */ static void destroy_handler(struct ddomain_binding* binding, const char* name, size_t len) { DRIVERKIT_DEBUG("Driver domain got destroy message for instance %s\n", name); errval_t err = driverkit_destroy(name); if (err_is_fail(err)) { DEBUG_ERR(err, "Destroying driver failed, report this back to Kaluga."); } err = binding->tx_vtbl.destroy_response(binding, NOP_CONT, err); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Sending reply failed."); } }