static int test2_dev_remove(ddf_dev_t *dev) { test2_t *test2 = (test2_t *)dev->driver_data; int rc; ddf_msg(LVL_DEBUG, "test2_dev_remove(%p)", dev); if (test2->fun_a != NULL) { rc = fun_remove(test2->fun_a, "a"); if (rc != EOK) return rc; } if (test2->fun_err != NULL) { rc = fun_remove(test2->fun_err, "ERROR"); if (rc != EOK) return rc; } if (test2->child != NULL) { rc = fun_remove(test2->child, "child"); if (rc != EOK) return rc; } if (test2->test1 != NULL) { rc = fun_remove(test2->test1, "test1"); if (rc != EOK) return rc; } return EOK; }
static int test1_dev_gone(ddf_dev_t *dev) { test1_t *test1 = (test1_t *)dev->driver_data; int rc; ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev); if (test1->fun_a != NULL) { rc = fun_unbind(test1->fun_a, "a"); if (rc != EOK) return rc; } if (test1->clone != NULL) { rc = fun_unbind(test1->clone, "clone"); if (rc != EOK) return rc; } if (test1->child != NULL) { rc = fun_unbind(test1->child, "child"); if (rc != EOK) return rc; } return EOK; }
/** Default handler for IPC methods not handled by DDF. * * @param fun Device function handling the call. * @param icallid Call id. * @param icall Call data. * */ static void default_connection_handler(ddf_fun_t *fun, ipc_callid_t icallid, ipc_call_t *icall) { const sysarg_t method = IPC_GET_IMETHOD(*icall); at_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun)); switch (method) { case KBDEV_SET_IND: { async_answer_0(icallid, ENOTSUP); break; } /* * This might be ugly but async_callback_receive_start makes no * difference for incorrect call and malloc failure. */ case IPC_M_CONNECT_TO_ME: { async_sess_t *sess = async_callback_receive_start(EXCHANGE_SERIALIZE, icall); /* Probably ENOMEM error, try again. */ if (sess == NULL) { ddf_msg(LVL_WARN, "Failed creating callback session"); async_answer_0(icallid, EAGAIN); break; } if (kbd->client_sess == NULL) { kbd->client_sess = sess; ddf_msg(LVL_DEBUG, "Set client session"); async_answer_0(icallid, EOK); } else { ddf_msg(LVL_ERROR, "Client session already set"); async_answer_0(icallid, ELIMIT); } break; } default: ddf_msg(LVL_ERROR, "Unknown method: %d.", (int)method); async_answer_0(icallid, EINVAL); break; } }
static int register_fun_and_add_to_category(ddf_dev_t *parent, const char *base_name, size_t index, const char *class_name, ddf_fun_t **pfun) { ddf_fun_t *fun = NULL; int rc; char *fun_name = NULL; rc = asprintf(&fun_name, "%s%zu", base_name, index); if (rc < 0) { ddf_msg(LVL_ERROR, "Failed to format string: %s", str_error(rc)); goto leave; } fun = ddf_fun_create(parent, fun_exposed, fun_name); if (fun == NULL) { ddf_msg(LVL_ERROR, "Failed creating function %s", fun_name); rc = ENOMEM; goto leave; } rc = ddf_fun_bind(fun); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed binding function %s: %s", fun_name, str_error(rc)); goto leave; } ddf_fun_add_to_category(fun, class_name); ddf_msg(LVL_NOTE, "Registered exposed function `%s'.", fun_name); leave: free(fun_name); if ((rc != EOK) && (fun != NULL)) { ddf_fun_destroy(fun); } *pfun = fun; return rc; }
static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess) { hda_t *hda = fun_to_hda(fun); ddf_msg(LVL_NOTE, "hda_set_event_session()"); hda_lock(hda); hda->ev_sess = sess; hda_unlock(hda); return EOK; }
static int fun_remove(ddf_fun_t *fun, const char *name) { int rc; ddf_msg(LVL_DEBUG, "fun_remove(%p, '%s')", fun, name); rc = ddf_fun_offline(fun); if (rc != EOK) { ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name); return rc; } rc = ddf_fun_unbind(fun); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name); return rc; } ddf_fun_destroy(fun); return EOK; }
static int hda_start_capture(ddf_fun_t *fun, unsigned frames, unsigned channels, unsigned rate, pcm_sample_format_t format) { hda_t *hda = fun_to_hda(fun); int rc; ddf_msg(LVL_NOTE, "hda_start_capture()"); hda_lock(hda); if (hda->pcm_stream != NULL) { hda_unlock(hda); return EBUSY; } /* XXX Choose appropriate parameters */ uint32_t fmt; /* 48 kHz, 16-bits, 1 channel */ fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1; ddf_msg(LVL_NOTE, "hda_start_capture() - create input stream"); hda->pcm_stream = hda_stream_create(hda, sdir_input, hda->pcm_buffers, fmt); if (hda->pcm_stream == NULL) { hda_unlock(hda); return EIO; } rc = hda_in_converter_setup(hda->ctl->codec, hda->pcm_stream); if (rc != EOK) { hda_stream_destroy(hda->pcm_stream); hda->pcm_stream = NULL; hda_unlock(hda); return rc; } hda->capturing = true; hda_stream_start(hda->pcm_stream); hda_unlock(hda); return EOK; }
static bool mac_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, mac_fun_t *fun_proto) { ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name); ddf_fun_t *fnode = NULL; int rc; /* Create new device. */ fnode = ddf_fun_create(dev, fun_inner, name); if (fnode == NULL) goto failure; mac_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(mac_fun_t)); *fun = *fun_proto; /* Add match ID */ rc = ddf_fun_add_match_id(fnode, str_match_id, 100); if (rc != EOK) goto failure; /* Set provided operations to the device. */ ddf_fun_set_ops(fnode, &mac_fun_ops); /* Register function. */ if (ddf_fun_bind(fnode) != EOK) { ddf_msg(LVL_ERROR, "Failed binding function %s.", name); goto failure; } return true; failure: if (fnode != NULL) ddf_fun_destroy(fnode); ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name); return false; }
static async_sess_t *hda_get_event_session(ddf_fun_t *fun) { hda_t *hda = fun_to_hda(fun); async_sess_t *sess; ddf_msg(LVL_NOTE, "hda_get_event_session()"); hda_lock(hda); sess = hda->ev_sess; hda_unlock(hda); return sess; }
/** Get the root device. * * @param dev Device which is root of the whole device tree * (both of HW and pseudo devices). * * @return Zero on success, negative error number otherwise. * */ static int mac_dev_add(ddf_dev_t *dev) { #if 0 /* Register functions */ if (!mac_add_fun(dev, "pci0", "intel_pci", &pci_data)) ddf_msg(LVL_ERROR, "Failed to add functions for Mac platform."); #else (void)pci_data; (void)mac_add_fun; #endif return EOK; }
/** Add the root device. * * @param dev Device which is root of the whole device tree * (both of HW and pseudo devices). * * @return Zero on success, negative error number otherwise. * */ static int rootamdm37x_dev_add(ddf_dev_t *dev) { assert(dev); amdm37x_t *device = ddf_dev_data_alloc(dev, sizeof(amdm37x_t)); if (!device) return ENOMEM; int ret = amdm37x_init(device, DEBUG_CM); if (ret != EOK) { ddf_msg(LVL_FATAL, "Failed to setup hw access!.\n"); return ret; } /* Set dplls to ON and automatic */ amdm37x_setup_dpll_on_autoidle(device); /* Enable function and interface clocks */ amdm37x_usb_clocks_set(device, true); /* Init TLL */ ret = amdm37x_usb_tll_init(device); if (ret != EOK) { ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n"); amdm37x_usb_clocks_set(device, false); return ret; } /* Register functions */ if (rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK) ddf_msg(LVL_ERROR, "Failed to add OHCI function for " "BeagleBoard-xM platform."); if (rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK) ddf_msg(LVL_ERROR, "Failed to add EHCI function for " "BeagleBoard-xM platform."); if (rootamdm37x_add_fun(dev, "dispc", "amdm37x&dispc", &ehci) != EOK) ddf_msg(LVL_ERROR, "Failed to add dispc function for " "BeagleBoard-xM platform."); return EOK; }
static int rootamdm37x_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, const rootamdm37x_fun_t *fun) { ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name); /* Create new device function. */ ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); if (fnode == NULL) return ENOMEM; /* Add match id */ int ret = ddf_fun_add_match_id(fnode, str_match_id, 100); if (ret != EOK) { ddf_fun_destroy(fnode); return ret; } /* Alloc needed data */ rootamdm37x_fun_t *rf = ddf_fun_data_alloc(fnode, sizeof(rootamdm37x_fun_t)); if (!rf) { ddf_fun_destroy(fnode); return ENOMEM; } *rf = *fun; /* Set provided operations to the device. */ ddf_fun_set_ops(fnode, &rootamdm37x_fun_ops); /* Register function. */ ret = ddf_fun_bind(fnode); if (ret != EOK) { ddf_msg(LVL_ERROR, "Failed binding function %s.", name); ddf_fun_destroy(fnode); return ret; } return EOK; }
/** Simulate plugging and surprise unplugging. * * @param arg Parent device structure (ddf_dev_t *). * @return Always EOK. */ static int plug_unplug(void *arg) { test2_t *test2 = (test2_t *) arg; ddf_fun_t *fun_a; int rc; async_usleep(1000); (void) register_fun_verbose(test2->dev, "child driven by the same task", "child", "virtual&test2", 10, &test2->child); (void) register_fun_verbose(test2->dev, "child driven by test1", "test1", "virtual&test1", 10, &test2->test1); fun_a = ddf_fun_create(test2->dev, fun_exposed, "a"); if (fun_a == NULL) { ddf_msg(LVL_ERROR, "Failed creating function 'a'."); return ENOMEM; } rc = ddf_fun_bind(fun_a); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed binding function 'a'."); return rc; } ddf_fun_add_to_category(fun_a, "virtual"); test2->fun_a = fun_a; async_usleep(10000000); ddf_msg(LVL_NOTE, "Unbinding function test1."); ddf_fun_unbind(test2->test1); async_usleep(1000000); ddf_msg(LVL_NOTE, "Unbinding function child."); ddf_fun_unbind(test2->child); return EOK; }
/** Initialize a new ddf driver instance of the driver * * @param[in] device DDF instance of the device to initialize. * * @return Error code. * */ static int at_kbd_add(ddf_dev_t *device) { int rc; if (!device) return EINVAL; at_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(at_kbd_t)); if (kbd == NULL) { ddf_msg(LVL_ERROR, "Failed to allocate AT_KBD driver instance."); return ENOMEM; } rc = at_kbd_init(kbd, device); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed to initialize AT_KBD driver: %s.", str_error(rc)); return rc; } ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", ddf_dev_get_name(device), ddf_dev_get_handle(device)); return EOK; }
static int hda_stop_capture(ddf_fun_t *fun, bool immediate) { hda_t *hda = fun_to_hda(fun); ddf_msg(LVL_NOTE, "hda_stop_capture()"); hda_lock(hda); hda_stream_stop(hda->pcm_stream); hda_stream_reset(hda->pcm_stream); hda->capturing = false; hda_stream_destroy(hda->pcm_stream); hda->pcm_stream = NULL; hda_unlock(hda); hda_pcm_event(hda, PCM_EVENT_CAPTURE_TERMINATED); return EOK; }
static int hda_release_buffer(ddf_fun_t *fun) { hda_t *hda = fun_to_hda(fun); hda_lock(hda); ddf_msg(LVL_NOTE, "hda_release_buffer()"); if (hda->pcm_buffers == NULL) { hda_unlock(hda); return EINVAL; } hda_stream_buffers_free(hda->pcm_buffers); hda->pcm_buffers = NULL; hda_unlock(hda); return EOK; }
/** Initialize a new ddf driver instance * * @param[in] device DDF instance of the device to initialize. * @return Error code. */ static int mouse_add(ddf_dev_t *device) { if (!device) return EINVAL; #define CHECK_RET_RETURN(ret, message...) \ if (ret != EOK) { \ ddf_msg(LVL_ERROR, message); \ return ret; \ } else (void)0 ps2_mouse_t *mouse = ddf_dev_data_alloc(device, sizeof(ps2_mouse_t)); int ret = (mouse == NULL) ? ENOMEM : EOK; CHECK_RET_RETURN(ret, "Failed to allocate mouse driver instance."); ret = ps2_mouse_init(mouse, device); CHECK_RET_RETURN(ret, "Failed to initialize mouse driver: %s.", str_error(ret)); ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", device->name, device->handle); return EOK; }
static int test3_dev_remove(ddf_dev_t *dev) { test3_t *test3 = (test3_t *)dev->driver_data; char *fun_name; int rc; size_t i; for (i = 0; i < NUM_FUNCS; i++) { rc = asprintf(&fun_name, "test3_%zu", i); if (rc < 0) { ddf_msg(LVL_ERROR, "Failed to format string: %s", str_error(rc)); return ENOMEM; } rc = fun_remove(test3->fun[i], fun_name); if (rc != EOK) return rc; free(fun_name); } return EOK; }
/** Initialize a new ddf driver instance of the driver * * @param[in] device DDF instance of the device to initialize. * @return Error code. */ static int xt_kbd_add(ddf_dev_t *device) { if (!device) return EINVAL; #define CHECK_RET_RETURN(ret, message...) \ if (ret != EOK) { \ ddf_msg(LVL_ERROR, message); \ return ret; \ } else (void)0 xt_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(xt_kbd_t)); int ret = (kbd == NULL) ? ENOMEM : EOK; CHECK_RET_RETURN(ret, "Failed to allocate XT/KBD driver instance."); ret = xt_kbd_init(kbd, device); CHECK_RET_RETURN(ret, "Failed to initialize XT_KBD driver: %s.", str_error(ret)); ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", ddf_dev_get_name(device), ddf_dev_get_handle(device)); return EOK; }
/** Initialize i8042 driver structure. * * @param dev Driver structure to initialize. * @param regs I/O address of registers. * @param reg_size size of the reserved I/O address space. * @param irq_kbd IRQ for primary port. * @param irq_mouse IRQ for aux port. * @param ddf_dev DDF device structure of the device. * * @return Error code. * */ int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd, int irq_mouse, ddf_dev_t *ddf_dev) { const size_t range_count = sizeof(i8042_ranges) / sizeof(irq_pio_range_t); irq_pio_range_t ranges[range_count]; const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); irq_cmd_t cmds[cmd_count]; int rc; bool kbd_bound = false; bool aux_bound = false; dev->kbd_fun = NULL; dev->aux_fun = NULL; if (reg_size < sizeof(i8042_regs_t)) { rc = EINVAL; goto error; } if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) { rc = EIO; goto error; } dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a"); if (dev->kbd_fun == NULL) { rc = ENOMEM; goto error; }; rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); if (rc != EOK) goto error; dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b"); if (dev->aux_fun == NULL) { rc = ENOMEM; goto error; } rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); if (rc != EOK) goto error; ddf_fun_set_ops(dev->kbd_fun, &ops); ddf_fun_set_ops(dev->aux_fun, &ops); buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE); buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE); fibril_mutex_initialize(&dev->write_guard); rc = ddf_fun_bind(dev->kbd_fun); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.", ddf_fun_get_name(dev->kbd_fun)); goto error; } kbd_bound = true; rc = ddf_fun_bind(dev->aux_fun); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.", ddf_fun_get_name(dev->aux_fun)); goto error; } aux_bound = true; /* Disable kbd and aux */ wait_ready(dev); pio_write_8(&dev->regs->status, i8042_CMD_WRITE_CMDB); wait_ready(dev); pio_write_8(&dev->regs->data, i8042_KBD_DISABLE | i8042_AUX_DISABLE); /* Flush all current IO */ while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL) (void) pio_read_8(&dev->regs->data); memcpy(ranges, i8042_ranges, sizeof(i8042_ranges)); ranges[0].base = (uintptr_t) regs; memcpy(cmds, i8042_cmds, sizeof(i8042_cmds)); cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status); cmds[3].addr = (void *) &(((i8042_regs_t *) regs)->data); irq_code_t irq_code = { .rangecount = range_count, .ranges = ranges, .cmdcount = cmd_count, .cmds = cmds }; rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler, &irq_code); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.", ddf_dev_get_name(ddf_dev)); goto error; } rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler, &irq_code); if (rc != EOK) { ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.", ddf_dev_get_name(ddf_dev)); goto error; } /* Enable interrupts */ async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev); assert(parent_sess != NULL); const bool enabled = hw_res_enable_interrupt(parent_sess); if (!enabled) { log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable interrupts: %s.", ddf_dev_get_name(ddf_dev)); rc = EIO; goto error; } /* Enable port interrupts. */ wait_ready(dev); pio_write_8(&dev->regs->status, i8042_CMD_WRITE_CMDB); wait_ready(dev); pio_write_8(&dev->regs->data, i8042_KBD_IE | i8042_KBD_TRANSLATE | i8042_AUX_IE); return EOK; error: if (kbd_bound) ddf_fun_unbind(dev->kbd_fun); if (aux_bound) ddf_fun_unbind(dev->aux_fun); if (dev->kbd_fun != NULL) ddf_fun_destroy(dev->kbd_fun); if (dev->aux_fun != NULL) ddf_fun_destroy(dev->aux_fun); return rc; }
/** Get data and parse scancodes. * * @param arg Pointer to at_kbd_t structure. * * @return EIO on error. * */ static int polling(void *arg) { const at_kbd_t *kbd = arg; assert(kbd); assert(kbd->parent_sess); async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess); while (true) { if (!parent_exch) parent_exch = async_exchange_begin(kbd->parent_sess); uint8_t code = 0; ssize_t size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; const unsigned int *map; size_t map_size; if (code == KBD_SCANCODE_SET_EXTENDED) { map = scanmap_e0; map_size = sizeof(scanmap_e0) / sizeof(unsigned int); size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; } else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) { size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x14) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x77) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xe1) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xf0) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x14) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xf0) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code == 0x77) push_event(kbd->client_sess, KEY_PRESS, KC_BREAK); continue; } else { map = scanmap_simple; map_size = sizeof(scanmap_simple) / sizeof(unsigned int); } kbd_event_type_t type; if (code == KBD_SCANCODE_KEY_RELEASE) { type = KEY_RELEASE; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; } else { type = KEY_PRESS; } const unsigned int key = (code < map_size) ? map[code] : 0; if (key != 0) push_event(kbd->client_sess, type, key); else ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code); } }
/** Get data and parse scancodes. * * @param arg Pointer to xt_kbd_t structure. * * @return EIO on error. * */ static int polling(void *arg) { const xt_kbd_t *kbd = arg; assert(kbd); assert(kbd->parent_sess); async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess); while (true) { if (!parent_exch) parent_exch = async_exchange_begin(kbd->parent_sess); const unsigned int *map = scanmap_simple; size_t map_size = sizeof(scanmap_simple) / sizeof(unsigned int); uint8_t code = 0; ssize_t size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; /* Ignore AT command reply */ if ((code == KBD_ACK) || (code == KBD_RESEND)) continue; /* Extended set */ if (code == KBD_SCANCODE_SET_EXTENDED) { map = scanmap_e0; map_size = sizeof(scanmap_e0) / sizeof(unsigned int); size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; /* Handle really special keys */ if (code == 0x2a) { /* Print Screen */ size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xe0) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code == 0x37) push_event(kbd->client_sess, KEY_PRESS, KC_PRTSCR); continue; } if (code == 0x46) { /* Break */ size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xe0) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code == 0xc6) push_event(kbd->client_sess, KEY_PRESS, KC_BREAK); continue; } } /* Extended special set */ if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) { size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x1d) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x45) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0xe1) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code != 0x9d) continue; size = chardev_read(parent_exch, &code, 1); if (size != 1) return EIO; if (code == 0xc5) push_event(kbd->client_sess, KEY_PRESS, KC_PAUSE); continue; } /* Bit 7 indicates press/release */ const kbd_event_type_t type = (code & 0x80) ? KEY_RELEASE : KEY_PRESS; code &= ~0x80; const unsigned int key = (code < map_size) ? map[code] : 0; if (key != 0) push_event(kbd->client_sess, type, key); else ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code); } }
static int hda_get_buffer_position(ddf_fun_t *fun, size_t *pos) { ddf_msg(LVL_NOTE, "hda_get_buffer_position()"); return ENOTSUP; }
static int test2_fun_offline(ddf_fun_t *fun) { ddf_msg(LVL_DEBUG, "test2_fun_offline()"); return ddf_fun_offline(fun); }