/** 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); xt_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun)); switch (method) { case KBDEV_SET_IND: { /* * XT keyboards do not support setting mods, * assume AT keyboard with Scan Code Set 1. */ const unsigned mods = IPC_GET_ARG1(*icall); const uint8_t status = 0 | ((mods & KM_CAPS_LOCK) ? LI_CAPS : 0) | ((mods & KM_NUM_LOCK) ? LI_NUM : 0) | ((mods & KM_SCROLL_LOCK) ? LI_SCROLL : 0); uint8_t cmds[] = { KBD_CMD_SET_LEDS, status }; async_exch_t *exch = async_exchange_begin(kbd->parent_sess); const ssize_t size = chardev_write(exch, cmds, sizeof(cmds)); async_exchange_end(exch); async_answer_0(icallid, size < 0 ? size : EOK); 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; } }
void usb_device_destroy_ddf(ddf_dev_t *ddf_dev) { assert(ddf_dev); usb_device_t *usb_dev = ddf_dev_data_get(ddf_dev); assert(usb_dev); usb_device_fini(usb_dev); return; }
static void ne2k_dev_cleanup(ddf_dev_t *dev) { if (ddf_dev_data_get(dev) != NULL) { ne2k_t *ne2k = NE2K(dev); if (ne2k) { free(ne2k->code.ranges); free(ne2k->code.cmds); } nic_unbind_and_destroy(dev); } }
/** 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 hda_t *fun_to_hda(ddf_fun_t *fun) { return (hda_t *)ddf_dev_data_get(ddf_fun_get_dev(fun)); }
static sb_mixer_t *fun_to_mixer(ddf_fun_t *fun) { sb16_t *sb = (sb16_t *)ddf_dev_data_get(ddf_fun_get_dev(fun)); return &sb->mixer; }
/** Get i8042 soft state from device node. */ static i8042_t *dev_i8042(ddf_dev_t *dev) { return ddf_dev_data_get(dev); }
/** * @param dev DDF device associated with NIC * @return The associated NIC structure */ nic_t *nic_get_from_ddf_dev(ddf_dev_t *dev) { return (nic_t *) ddf_dev_data_get(dev); }
static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev) { sb16_t *sb16_dev = ddf_dev_data_get(dev); sb16_interrupt(sb16_dev); }