/* * EMU10k1 loader * * Copyright (c) 2003,2004 by Peter Zubaj * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "ld10k1.h" #include "ld10k1_fnc.h" #include "ld10k1_fnc_int.h" #include "ld10k1_debug.h" #include "ld10k1_error.h" #include "ld10k1_dump.h" #include "ld10k1_driver.h" #include "ld10k1_mixer.h" #include "comm.h" void ld10k1_fnc_prepare_free(); int ld10k1_fnc_patch_add(int data_conn, int op, int size); int ld10k1_fnc_patch_del(int data_conn, int op, int size); int ld10k1_fnc_patch_conn(int data_conn, int op, int size); int ld10k1_fnc_name_find(int data_conn, int op, int size); int ld10k1_fnc_name_rename(int data_conn, int op, int size); int ld10k1_fnc_dsp_init(int data_conn, int op, int size); int ld10k1_fnc_get_io_count(int data_conn, int op, int size); int ld10k1_fnc_get_io(int data_conn, int op, int size); int ld10k1_fnc_get_pio_count(int data_conn, int op, int size); int ld10k1_fnc_get_pio(int data_conn, int op, int size); int ld10k1_fnc_get_patches_info(int data_conn, int op, int size); int ld10k1_fnc_get_patch(int data_conn, int op, int size); int ld10k1_fnc_dump(int data_conn, int op, int size); int ld10k1_fnc_version(int data_conn, int op, int size); int ld10k1_fnc_get_points_info(int data_conn, int op, int size); int ld10k1_fnc_get_point_info(int data_conn, int op, int size); int ld10k1_fnc_get_dsp_info(int data_conn, int op, int size); ld10k1_dsp_mgr_t dsp_mgr; struct fnc_table_t { int fnc; int min_size; int max_size; int (*fnc_code)(int data_conn, int op, int size); }; struct fnc_table_t fnc_table[] = { {FNC_PATCH_ADD, sizeof(ld10k1_fnc_patch_add_t), sizeof(ld10k1_fnc_patch_add_t), ld10k1_fnc_patch_add}, {FNC_PATCH_DEL, sizeof(ld10k1_fnc_patch_del_t), sizeof(ld10k1_fnc_patch_del_t), ld10k1_fnc_patch_del}, {FNC_CONNECTION_ADD, sizeof(ld10k1_fnc_connection_t), sizeof(ld10k1_fnc_connection_t), ld10k1_fnc_patch_conn}, {FNC_CONNECTION_DEL, sizeof(ld10k1_fnc_connection_t), sizeof(ld10k1_fnc_connection_t), ld10k1_fnc_patch_conn}, {FNC_DEBUG, sizeof(ld10k1_fnc_debug_t), sizeof(ld10k1_fnc_debug_t), ld10k1_fnc_debug}, {FNC_PATCH_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_PATCH_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_FX_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_IN_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_OUT_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_PATCH_IN_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_PATCH_OUT_FIND, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_find}, {FNC_FX_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_IN_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_OUT_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_PATCH_IN_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_PATCH_OUT_RENAME, sizeof(ld10k1_fnc_name_t), sizeof(ld10k1_fnc_name_t), ld10k1_fnc_name_rename}, {FNC_GET_FX_COUNT, 0, 0, ld10k1_fnc_get_io_count}, {FNC_GET_IN_COUNT, 0, 0, ld10k1_fnc_get_io_count}, {FNC_GET_OUT_COUNT, 0, 0, ld10k1_fnc_get_io_count}, {FNC_GET_PIN_COUNT, sizeof(int), sizeof(int), ld10k1_fnc_get_pio_count}, {FNC_GET_POUT_COUNT, sizeof(int), sizeof(int), ld10k1_fnc_get_pio_count}, {FNC_GET_FX, sizeof(int), sizeof(int), ld10k1_fnc_get_io}, {FNC_GET_IN, sizeof(int), sizeof(int), ld10k1_fnc_get_io}, {FNC_GET_OUT, sizeof(int), sizeof(int), ld10k1_fnc_get_io}, {FNC_GET_PIN, sizeof(int) * 2, sizeof(int) * 2, ld10k1_fnc_get_pio}, {FNC_GET_POUT, sizeof(int) * 2, sizeof(int) * 2, ld10k1_fnc_get_pio}, {FNC_GET_PATCHES_INFO, 0, 0, ld10k1_fnc_get_patches_info}, {FNC_GET_PATCH, sizeof(int), sizeof(int), ld10k1_fnc_get_patch}, {FNC_DSP_INIT, 0, 0, ld10k1_fnc_dsp_init}, {FNC_DUMP, 0, 0, ld10k1_fnc_dump}, {FNC_VERSION, 0, 0, ld10k1_fnc_version}, {FNC_GET_POINTS_INFO, 0, 0, ld10k1_fnc_get_points_info}, {FNC_GET_POINT_INFO, sizeof(int), sizeof(int), ld10k1_fnc_get_point_info}, {FNC_GET_DSP_INFO, 0, 0, ld10k1_fnc_get_dsp_info}, {-1, 0, 0, NULL} }; ld10k1_dsp_mgr_t dsp_mgr; int send_response_ok(int conn_num) { return send_response(conn_num, FNC_OK, 0, NULL, 0); } int send_response_err(int conn_num, int err) { return send_response(conn_num, FNC_ERR, err, NULL, 0); } int send_response_wd(int conn_num, void *data, int data_size) { return send_response(conn_num, FNC_OK, 0, data, data_size); } struct ClientDefTag { int used; int socket; }; typedef struct ClientDefTag ClientDef; #define MAX_CLIENTS 10 ClientDef clients[MAX_CLIENTS]; int clients_count = 0; static void client_init() { int i; for (i = 0; i < MAX_CLIENTS; i++) clients[i].used = 0; clients_count = 0; } static int client_add() { int i; for (i = 0; i < MAX_CLIENTS; i++) if (clients[i].used == 0) { clients[i].used = 1; clients_count++; return i; } return -1; } static void client_del(int client) { if (client >= 0 && client < MAX_CLIENTS && clients[client].used == 1) { clients[client].used = 0; clients_count--; } } static int client_find_by_socket(int socket) { int i; for (i = 0; i < MAX_CLIENTS; i++) if (clients[i].socket == socket) return i; return -1; } int main_loop(comm_param *param, int audigy, const char *card_id, int tram_size, snd_ctl_t *ctlp) { fd_set active_fd_set/*, read_fd_set*/; int i, j, res = 0; __sighandler_t old_sig_pipe; int main_sock = 0; int data_sock = 0; int new_client = 0; int op = 0; int data_size = 0; int retval = 0; dsp_mgr.audigy = audigy; dsp_mgr.card_id = card_id; if (ld10k1_dsp_mgr_init(&dsp_mgr)) return -1; /* initialize id generators */ ld10k1_dsp_mgr_init_id_gen(&dsp_mgr); if (ld10k1_init_driver(&dsp_mgr, tram_size) < 0) { ld10k1_dsp_mgr_free(&dsp_mgr); return -1; } if (ld10k1_init_reserved_ctls(&dsp_mgr, ctlp) < 0) { ld10k1_dsp_mgr_free(&dsp_mgr); return -1; } old_sig_pipe = signal(SIGPIPE, SIG_IGN); param->server = 1; if ((main_sock = setup_comm(param)) < 0) goto error; if (listen_comm(main_sock)) goto error; /* Initialize the set of active sockets. */ client_init(); while (1) { /* Block until input arrives on one or more active sockets. */ FD_ZERO (&active_fd_set); FD_SET (main_sock, &active_fd_set); for (i = 0; i < MAX_CLIENTS; i++) if (clients[i].used) FD_SET(clients[i].socket, &active_fd_set); if (select(FD_SETSIZE, &active_fd_set, NULL, NULL, NULL) < 0) goto error; for (i = 0; i < FD_SETSIZE; i++) if (FD_ISSET (i, &active_fd_set)) { if (i == main_sock) { /* Connection request on original socket. */ if ((data_sock = accept_comm(main_sock)) < 0) goto error; new_client = client_add(); if (new_client < 0) free_comm(data_sock); else clients[new_client].socket = data_sock; /*FD_SET(data_sock, &active_fd_set);*/ } else { /* Data arriving on an already-connected socket. */ if (receive_request(i, &op, &data_size)) /*goto error;*/ op = -1; /* probably client closes */ if (op == FNC_CLOSE_CONN) { /* wait some time */ usleep(10000); goto e_close; } if (op >= 0) { /* search in function table */ res = 1; for (j = 0; fnc_table[j].fnc >= 0; j++) { if ((fnc_table[j].fnc == op) && (data_size >= fnc_table[j].min_size) && (data_size <= fnc_table[j].max_size)) { res = (*fnc_table[j].fnc_code)(i, op, data_size); break; } } if (!res) { if (send_response(i, FNC_OK, 0, NULL, 0) < 0) goto e_close; } else { if (send_response(i, FNC_ERR, res, NULL, 0) < 0) goto e_close; } } else { e_close: if (op != FNC_CLOSE_CONN) printf("error protocol fnc:%d - %d\n", op, res); client_del(client_find_by_socket(i)); /*FD_CLR (i, &active_fd_set);*/ /* close connection */ if (free_comm(i)) data_sock = 0; } } } } end: signal(SIGPIPE, old_sig_pipe); for (i = 0; i < MAX_CLIENTS; i++) if (clients[i].used) { client_del(i); free_comm(clients[i].socket); } free_comm(main_sock); ld10k1_free_reserved_ctls(&dsp_mgr); ld10k1_dsp_mgr_free(&dsp_mgr); return retval; error: retval = -1; goto end; } int ld10k1_fnc_receive_patch_info(int data_conn, ld10k1_dsp_patch_t *new_patch, int *where) { ld10k1_fnc_patch_add_t tmp_info; if (receive_msg_data(data_conn, &tmp_info, sizeof(ld10k1_fnc_patch_add_t)) < 0) return LD10K1_ERR_PROTOCOL; memcpy(new_patch, &(tmp_info.patch), sizeof(ld10k1_dsp_patch_t)); *where = tmp_info.where; new_patch->patch_name[MAX_NAME_LEN - 1] = '\n'; if (new_patch->in_count < 0 || new_patch->in_count > 32) return LD10K1_ERR_PROTOCOL_IN_COUNT; if (new_patch->out_count < 0 || new_patch->out_count > 32) return LD10K1_ERR_PROTOCOL_OUT_COUNT; if (new_patch->const_count < 0 || new_patch->const_count > 255) return LD10K1_ERR_PROTOCOL_CONST_COUNT; if (new_patch->static_count < 0 || new_patch->static_count > 255) return LD10K1_ERR_PROTOCOL_STATIC_COUNT; if (new_patch->dynamic_count < 0 || new_patch->dynamic_count > 255) return LD10K1_ERR_PROTOCOL_DYNAMIC_COUNT; if (new_patch->hw_count < 0 || new_patch->hw_count > 255) return LD10K1_ERR_PROTOCOL_HW_COUNT; if (new_patch->tram_count < 0 || new_patch->tram_count > 255) return LD10K1_ERR_PROTOCOL_TRAM_COUNT; if (new_patch->tram_acc_count < 0 || new_patch->tram_acc_count > 255) return LD10K1_ERR_PROTOCOL_TRAM_ACC_COUNT; if (new_patch->ctl_count < 0 || new_patch->ctl_count > 255) return LD10K1_ERR_PROTOCOL_CTL_COUNT; if (new_patch->instr_count < 0 || new_patch->instr_count > 512) return LD10K1_ERR_PROTOCOL_INSTR_COUNT; return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_in(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_p_in_out_t *new_in = NULL; int i; int err; if (!new_patch->in_count) return 0; if (!(new_in = (ld10k1_dsp_p_in_out_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_p_in_out_t) * new_patch->in_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->in_count; i++) { if (!ld10k1_dsp_mgr_name_new(&(new_patch->ins[i].name), new_in[i].name)) { err = LD10K1_ERR_NO_MEM; goto error; } } return send_response_ok(data_conn); error: free(new_in); return err; } int ld10k1_fnc_receive_patch_out(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_p_in_out_t *new_out = NULL; int i; int err; if (!new_patch->out_count) return 0; if (!(new_out = (ld10k1_dsp_p_in_out_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_p_in_out_t) * new_patch->out_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->out_count; i++) { if (!ld10k1_dsp_mgr_name_new(&(new_patch->outs[i].name), new_out[i].name)) { err = LD10K1_ERR_NO_MEM; goto error; } } return send_response_ok(data_conn); error: free(new_out); return err; } int ld10k1_fnc_receive_patch_const(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_p_const_static_t *new_const = NULL; int i; if (!new_patch->const_count) return 0; if (!(new_const = (ld10k1_dsp_p_const_static_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_p_const_static_t) * new_patch->const_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->const_count; i++) new_patch->consts[i].const_val = new_const[i].const_val; return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_sta(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_p_const_static_t *new_sta = NULL; int i; if (!new_patch->sta_count) return 0; if (!(new_sta = (ld10k1_dsp_p_const_static_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_p_const_static_t) * new_patch->sta_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->sta_count; i++) new_patch->stas[i].const_val = new_sta[i].const_val; return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_hw(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_p_hw_t *new_hw = NULL; int i; if (!new_patch->hw_count) return 0; if (!(new_hw = (ld10k1_dsp_p_hw_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_p_hw_t) * new_patch->hw_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->hw_count; i++) new_patch->hws[i].reg_idx = new_hw[i].hw_val; return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_tram_grp(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_tram_grp_t *new_tram_grp = NULL; int i; if (!new_patch->tram_count) return 0; if (!(new_tram_grp = (ld10k1_dsp_tram_grp_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_tram_grp_t) * new_patch->tram_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->tram_count; i++) { new_patch->tram_grp[i].grp_type = new_tram_grp[i].grp_type; new_patch->tram_grp[i].grp_size = new_tram_grp[i].grp_size; new_patch->tram_grp[i].grp_pos = new_tram_grp[i].grp_pos; } return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_tram_acc(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_tram_acc_t *new_tram_acc = NULL; int i; if (!new_patch->tram_acc_count) return 0; if (!(new_tram_acc = (ld10k1_dsp_tram_acc_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_tram_acc_t) * new_patch->tram_acc_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->tram_acc_count; i++) { new_patch->tram_acc[i].acc_type = new_tram_acc[i].acc_type; new_patch->tram_acc[i].acc_offset = new_tram_acc[i].acc_offset; new_patch->tram_acc[i].grp = new_tram_acc[i].grp; } return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_ctl(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_ctl_t *new_ctl = NULL; int i, j; if (!new_patch->ctl_count) return 0; if (!(new_ctl = (ld10k1_dsp_ctl_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_ctl_t) * new_patch->ctl_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->ctl_count; i++) { strncpy(new_patch->ctl[i].name, new_ctl[i].name, 43); new_patch->ctl[i].name[43] = '\0'; new_patch->ctl[i].index = -1; new_patch->ctl[i].want_index = new_ctl[i].index; new_patch->ctl[i].count = new_ctl[i].count; new_patch->ctl[i].vcount = new_ctl[i].vcount; new_patch->ctl[i].min = new_ctl[i].min; new_patch->ctl[i].max = new_ctl[i].max; new_patch->ctl[i].translation = new_ctl[i].translation; for (j = 0; j < new_patch->ctl[i].count; j++) new_patch->ctl[i].value[j] = new_ctl[i].value[j]; } return send_response_ok(data_conn); } int ld10k1_fnc_receive_patch_instr(int data_conn, ld10k1_patch_t *new_patch) { ld10k1_dsp_instr_t *new_instr = NULL; int i, j; if (!new_patch->instr_count) return 0; if (!(new_instr = (ld10k1_dsp_instr_t *)receive_msg_data_malloc(data_conn, sizeof(ld10k1_dsp_instr_t) * new_patch->instr_count))) return LD10K1_ERR_PROTOCOL; /* copy values */ for (i = 0; i < new_patch->instr_count; i++) { new_patch->instr[i].op_code = new_instr[i].op_code; for (j = 0; j < 4; j++) new_patch->instr[i].arg[j] = new_instr[i].arg[j]; new_patch->instr[i].used = 1; new_patch->instr[i].modified = 1; } return send_response_ok(data_conn); } int ld10k1_fnc_patch_add(int data_conn, int op, int size) { int err; int loaded[2]; int where; ld10k1_dsp_patch_t new_patch_info; /* allocate new patch */ ld10k1_patch_t *new_patch = NULL; if ((err = ld10k1_fnc_receive_patch_info(data_conn, &new_patch_info, &where)) < 0) goto error; if (!(new_patch = ld10k1_dsp_mgr_patch_new())) { err = LD10K1_ERR_NO_MEM; goto error; } /* name */ if (!ld10k1_dsp_mgr_name_new(&(new_patch->patch_name), new_patch_info.patch_name)) { err = LD10K1_ERR_NO_MEM; goto error; } /* set sizes */ if (new_patch_info.in_count) if (!ld10k1_dsp_mgr_patch_in_new(new_patch, new_patch_info.in_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.out_count) if (!ld10k1_dsp_mgr_patch_out_new(new_patch, new_patch_info.out_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.const_count) if (!ld10k1_dsp_mgr_patch_const_new(new_patch, new_patch_info.const_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.static_count) if (!ld10k1_dsp_mgr_patch_sta_new(new_patch, new_patch_info.static_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.dynamic_count) if (!ld10k1_dsp_mgr_patch_dyn_new(new_patch, new_patch_info.dynamic_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.hw_count) if (!ld10k1_dsp_mgr_patch_hw_new(new_patch, new_patch_info.hw_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.tram_count) if (!ld10k1_dsp_mgr_patch_tram_new(new_patch, new_patch_info.tram_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.tram_acc_count) if (!ld10k1_dsp_mgr_patch_tram_acc_new(new_patch, new_patch_info.tram_acc_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (new_patch_info.ctl_count) if (!ld10k1_dsp_mgr_patch_ctl_new(new_patch,new_patch_info.ctl_count)) { err = LD10K1_ERR_NO_MEM; goto error; } if (!ld10k1_dsp_mgr_patch_instr_new(new_patch, new_patch_info.instr_count)) { err = LD10K1_ERR_NO_MEM; goto error; } /* receive next parts */ if (new_patch_info.in_count) if ((err = ld10k1_fnc_receive_patch_in(data_conn, new_patch)) < 0) goto error; if (new_patch_info.out_count) if ((err = ld10k1_fnc_receive_patch_out(data_conn, new_patch)) < 0) goto error; if (new_patch_info.const_count) if ((err = ld10k1_fnc_receive_patch_const(data_conn, new_patch)) < 0) goto error; if (new_patch_info.static_count) if ((err = ld10k1_fnc_receive_patch_sta(data_conn, new_patch)) < 0) goto error; if (new_patch_info.hw_count) if ((err = ld10k1_fnc_receive_patch_hw(data_conn, new_patch)) < 0) goto error; if (new_patch_info.tram_count) if ((err = ld10k1_fnc_receive_patch_tram_grp(data_conn, new_patch)) < 0) goto error; if (new_patch_info.tram_acc_count) if ((err = ld10k1_fnc_receive_patch_tram_acc(data_conn, new_patch)) < 0) goto error; if (new_patch_info.ctl_count) if ((err = ld10k1_fnc_receive_patch_ctl(data_conn, new_patch)) < 0) goto error; if ((err = ld10k1_fnc_receive_patch_instr(data_conn, new_patch)) < 0) goto error; /* check patch */ if ((err = ld10k1_patch_fnc_check_patch(&dsp_mgr, new_patch)) < 0) goto error; /* load patch */ if ((err = ld10k1_dsp_mgr_patch_load(&dsp_mgr, new_patch, where, loaded)) < 0) goto error; if ((err = send_response_wd(data_conn, loaded, sizeof(loaded))) < 0) return err; return 0; error: if (new_patch) ld10k1_dsp_mgr_patch_free(new_patch); return err; } int ld10k1_fnc_patch_del(int data_conn, int op, int size) { ld10k1_fnc_patch_del_t patch_info; int err; if ((err = receive_msg_data(data_conn, &patch_info, sizeof(ld10k1_fnc_patch_del_t))) < 0) return err; return ld10k1_patch_fnc_del(&dsp_mgr, &patch_info); } int ld10k1_fnc_patch_conn(int data_conn, int op, int size) { ld10k1_fnc_connection_t connection_info; int err; int conn_id; if ((err = receive_msg_data(data_conn, &connection_info, sizeof(ld10k1_fnc_connection_t))) < 0) return err; if ((err = ld10k1_connection_fnc(&dsp_mgr, &connection_info, &conn_id)) < 0) return err; return send_response_wd(data_conn, &conn_id, sizeof(conn_id)); } int ld10k1_fnc_name_find(int data_conn, int op, int size) { ld10k1_fnc_name_t name_info; int i; static int ret; int err; ld10k1_patch_t *patch; ret = -1; if ((err = receive_msg_data(data_conn, &name_info, sizeof(ld10k1_fnc_name_t))) < 0) return err; name_info.name[MAX_NAME_LEN - 1] = '\0'; switch (op) { case FNC_PATCH_FIND: for (i = 0; i < EMU10K1_PATCH_MAX ; i++) if (dsp_mgr.patch_ptr[i]) if (strcmp(dsp_mgr.patch_ptr[i]->patch_name, name_info.name) == 0) { ret = i; break; } break; case FNC_FX_FIND: for (i = 0; i < dsp_mgr.fx_count ; i++) if (dsp_mgr.fxs[i].name) if (strcmp(dsp_mgr.fxs[i].name, name_info.name) == 0) { ret = i; break; } break; case FNC_IN_FIND: for (i = 0; i < dsp_mgr.in_count ; i++) if (dsp_mgr.ins[i].name) if (strcmp(dsp_mgr.ins[i].name, name_info.name) == 0) { ret = i; break; } break; case FNC_OUT_FIND: for (i = 0; i < dsp_mgr.out_count ; i++) if (dsp_mgr.outs[i].name) if (strcmp(dsp_mgr.outs[i].name, name_info.name) == 0) { ret = i; break; } break; case FNC_PATCH_IN_FIND : if (name_info.patch_num >= 0 || name_info.patch_num < EMU10K1_PATCH_MAX) { patch = dsp_mgr.patch_ptr[name_info.patch_num]; if (patch) for (i = 0; i < patch->in_count ; i++) if (patch->ins[i].name) if (strcmp(patch->ins[i].name, name_info.name) == 0) { ret = i; break; } } break; case FNC_PATCH_OUT_FIND : if (name_info.patch_num >= 0 || name_info.patch_num < EMU10K1_PATCH_MAX) { patch = dsp_mgr.patch_ptr[name_info.patch_num]; if (patch) for (i = 0; i < patch->out_count ; i++) if (patch->outs[i].name) if (strcmp(patch->outs[i].name, name_info.name) == 0) { ret = i; break; } } break; } return send_response_wd(data_conn, &ret, sizeof(ret)); } int ld10k1_fnc_name_rename(int data_conn, int op, int size) { ld10k1_fnc_name_t name_info; int ret; int err; ld10k1_patch_t *patch; ret = -1; if ((err = receive_msg_data(data_conn, &name_info, sizeof(ld10k1_fnc_name_t))) < 0) return err; name_info.name[MAX_NAME_LEN - 1] = '\0'; switch (op) { case FNC_PATCH_RENAME: if (name_info.patch_num >= 0 || name_info.patch_num < EMU10K1_PATCH_MAX) { patch = dsp_mgr.patch_ptr[name_info.patch_num]; if (patch) { if (!ld10k1_dsp_mgr_name_new(&(patch->patch_name), name_info.name)) return LD10K1_ERR_PATCH_RENAME; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; break; case FNC_FX_RENAME: if (name_info.gpr < 0 || name_info.gpr >= dsp_mgr.fx_count) return LD10K1_ERR_UNKNOWN_REG_NUM; if (!ld10k1_dsp_mgr_name_new(&(dsp_mgr.fxs[name_info.gpr].name), name_info.name)) return LD10K1_ERR_REG_RENAME; break; case FNC_IN_RENAME: if (name_info.gpr < 0 || name_info.gpr >= dsp_mgr.in_count) return LD10K1_ERR_UNKNOWN_REG_NUM; if (!ld10k1_dsp_mgr_name_new(&(dsp_mgr.ins[name_info.gpr].name), name_info.name)) return LD10K1_ERR_REG_RENAME; break; case FNC_OUT_RENAME: if (name_info.gpr < 0 || name_info.gpr >= dsp_mgr.out_count) return LD10K1_ERR_UNKNOWN_REG_NUM; if (!ld10k1_dsp_mgr_name_new(&(dsp_mgr.outs[name_info.gpr].name), name_info.name)) return LD10K1_ERR_REG_RENAME; break; case FNC_PATCH_IN_RENAME: if (name_info.patch_num >= 0 || name_info.patch_num < EMU10K1_PATCH_MAX) { patch = dsp_mgr.patch_ptr[name_info.patch_num]; if (patch) { if (name_info.gpr < 0 || name_info.gpr >= patch->in_count) return LD10K1_ERR_UNKNOWN_PATCH_REG_NUM; if (!ld10k1_dsp_mgr_name_new(&(patch->ins[name_info.gpr].name), name_info.name)) return LD10K1_ERR_PATCH_REG_RENAME; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; break; case FNC_PATCH_OUT_RENAME: if (name_info.patch_num >= 0 || name_info.patch_num < EMU10K1_PATCH_MAX) { patch = dsp_mgr.patch_ptr[name_info.patch_num]; if (patch) { if (name_info.gpr < 0 || name_info.gpr >= patch->out_count) return LD10K1_ERR_UNKNOWN_PATCH_REG_NUM; if (!ld10k1_dsp_mgr_name_new(&(patch->outs[name_info.gpr].name), name_info.name)) return LD10K1_ERR_PATCH_REG_RENAME; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; break; } return 0; } int ld10k1_fnc_dsp_init(int data_conn, int op, int size) { int audigy; int err, i; ld10k1_reserved_ctl_list_item_t *rlist; int save_ids[EMU10K1_PATCH_MAX]; audigy = dsp_mgr.audigy; rlist = dsp_mgr.reserved_ctl_list; /* FIXME - hack to save reserved ctls and ids */ for (i = 0; i < EMU10K1_PATCH_MAX; i++) save_ids[i] = dsp_mgr.patch_id_gens[i]; ld10k1_dsp_mgr_free(&dsp_mgr); memset(&dsp_mgr, 0, sizeof(dsp_mgr)); dsp_mgr.audigy = audigy; if ((err = ld10k1_dsp_mgr_init(&dsp_mgr)) < 0) return err; dsp_mgr.reserved_ctl_list = rlist; /* hack to seve reserved ctls */ for (i = 0; i < EMU10K1_PATCH_MAX; i++) dsp_mgr.patch_id_gens[i] = save_ids[i]; return ld10k1_init_driver(&dsp_mgr, -1); } int ld10k1_fnc_get_io_count(int data_conn, int op, int size) { int reg_count; reg_count = 0; if (op == FNC_GET_FX_COUNT) /* fxs */ reg_count = dsp_mgr.fx_count; else if (op == FNC_GET_IN_COUNT) /* ins */ reg_count = dsp_mgr.in_count; else /* outs */ reg_count = dsp_mgr.out_count; return send_response_wd(data_conn, ®_count, sizeof(int)); } int ld10k1_fnc_get_io(int data_conn, int op, int size) { int err; int reg_count; int reg_num; ld10k1_fnc_get_io_t io; if ((err = receive_msg_data(data_conn, ®_num, sizeof(int))) < 0) return err; if (op == FNC_GET_FX) /* fx */ reg_count = dsp_mgr.fx_count; else if (op == FNC_GET_IN) /* in */ reg_count = dsp_mgr.in_count; else /* out */ reg_count = dsp_mgr.out_count; if (reg_num < 0 || reg_num >= reg_count) return LD10K1_ERR_UNKNOWN_REG_NUM; if (op == FNC_GET_FX) { /* fx */ memset(io.name, 0, sizeof(io.name)); if (dsp_mgr.fxs[reg_num].name) strcpy(io.name, dsp_mgr.fxs[reg_num].name); } else if (op == FNC_GET_IN) { /* in */ memset(io.name, 0, sizeof(io.name)); if (dsp_mgr.ins[reg_num].name) strcpy(io.name, dsp_mgr.ins[reg_num].name); } else { /* out */ memset(io.name, 0, sizeof(io.name)); if (dsp_mgr.outs[reg_num].name) strcpy(io.name, dsp_mgr.outs[reg_num].name); } return send_response_wd(data_conn, &io, sizeof(ld10k1_fnc_get_io_t)); } int ld10k1_fnc_get_pio_count(int data_conn, int op, int size) { int patch_num; int err; int reg_count; ld10k1_patch_t *patch; if ((err = receive_msg_data(data_conn, &patch_num, sizeof(int))) < 0) return err; reg_count = 0; /* patch */ if (patch_num >= 0 && patch_num < EMU10K1_PATCH_MAX) { /* patch register */ patch = dsp_mgr.patch_ptr[patch_num]; if (!patch) return LD10K1_ERR_UNKNOWN_PATCH_NUM; if (op == FNC_GET_PIN_COUNT) /* pin */ reg_count = patch->in_count; else /* pout */ reg_count = patch->out_count; } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; return send_response_wd(data_conn, ®_count, sizeof(int)); } int ld10k1_fnc_get_pio(int data_conn, int op, int size) { int patch_num; int reg_num; int err; int tmp_num[2]; int reg_count; ld10k1_fnc_get_io_t io; ld10k1_patch_t *patch; if ((err = receive_msg_data(data_conn, tmp_num, sizeof(int) * 2)) < 0) return err; patch_num = tmp_num[0]; reg_num = tmp_num[1]; reg_count = 0; /* patch */ if (patch_num >= 0 && patch_num < EMU10K1_PATCH_MAX) { /* patch register */ patch = dsp_mgr.patch_ptr[patch_num]; if (!patch) return LD10K1_ERR_UNKNOWN_PATCH_NUM; if (op == FNC_GET_PIN) /* pin */ reg_count = patch->in_count; else /* pout */ reg_count = patch->out_count; if (reg_num < 0 || reg_num >= reg_count) return LD10K1_ERR_UNKNOWN_PATCH_REG_NUM; if (op == FNC_GET_PIN) { /* pin */ memset(io.name, 0, sizeof(io.name)); if (patch->ins[reg_num].name) strcpy(io.name, patch->ins[reg_num].name); } else { /* pout */ memset(io.name, 0, sizeof(io.name)); if (patch->outs[reg_num].name) strcpy(io.name, patch->outs[reg_num].name); } } else return LD10K1_ERR_UNKNOWN_PATCH_NUM; return send_response_wd(data_conn, &io, sizeof(ld10k1_fnc_get_io_t)); } int ld10k1_fnc_get_patches_info(int data_conn, int op, int size) { int i, idx, j; ld10k1_fnc_patches_info_t *info; ld10k1_patch_t *patch; info = NULL; if (dsp_mgr.patch_count >= 0) { /* alloc space */ info = (ld10k1_fnc_patches_info_t *)malloc(sizeof(ld10k1_fnc_patches_info_t) * dsp_mgr.patch_count); if (!info) return LD10K1_ERR_NO_MEM; memset(info, 0, sizeof(ld10k1_fnc_patches_info_t) * dsp_mgr.patch_count); /* copy values */ for (i = 0, j = 0; i < dsp_mgr.patch_count; i++) { idx = dsp_mgr.patch_order[i]; patch = dsp_mgr.patch_ptr[idx]; if (patch) { info[j].patch_num = idx; info[j].id = patch->id; strcpy(info[j].patch_name, patch->patch_name); j++; } } } return send_response_wd(data_conn, info, sizeof(ld10k1_fnc_patches_info_t) * dsp_mgr.patch_count); } int ld10k1_fnc_version(int data_conn, int op, int size) { ld10k1_fnc_version_t version; strcpy(version.ld10k1_version, VERSION); return send_response_wd(data_conn, &version, sizeof(ld10k1_fnc_version_t)); } int ld10k1_fnc_send_patch_in(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_p_in_out_t *ins = NULL; if (patch->in_count) { ins = (ld10k1_dsp_p_in_out_t *)malloc(sizeof(ld10k1_dsp_p_in_out_t) * patch->in_count); if (!ins) return LD10K1_ERR_NO_MEM; memset(ins, 0, sizeof(ld10k1_dsp_p_in_out_t) * patch->in_count); for (i = 0; i < patch->in_count; i++) { if (patch->ins[i].name) strcpy(ins[i].name, patch->ins[i].name); else ins[i].name[0] = '\0'; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, ins, sizeof(ld10k1_dsp_p_in_out_t) * patch->in_count)) < 0) { free(ins); return err; } free(ins); } return 0; } int ld10k1_fnc_send_patch_out(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_p_in_out_t *outs = NULL; if (patch->out_count) { outs = (ld10k1_dsp_p_in_out_t *)malloc(sizeof(ld10k1_dsp_p_in_out_t) * patch->out_count); if (!outs) return LD10K1_ERR_NO_MEM; memset(outs, 0, sizeof(ld10k1_dsp_p_in_out_t) * patch->out_count); for (i = 0; i < patch->out_count; i++) { if (patch->outs[i].name) strcpy(outs[i].name, patch->outs[i].name); else outs[i].name[0] = '\0'; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, outs, sizeof(ld10k1_dsp_p_in_out_t) * patch->out_count)) < 0) { free(outs); return err; } free(outs); } return 0; } int ld10k1_fnc_send_patch_const(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_p_const_static_t *consts = NULL; if (patch->const_count) { consts = (ld10k1_dsp_p_const_static_t *)malloc(sizeof(ld10k1_dsp_p_const_static_t) * patch->const_count); if (!consts) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->const_count; i++) consts[i].const_val = patch->consts[i].const_val; if ((err = send_response(data_conn, FNC_CONTINUE, 0, consts, sizeof(ld10k1_dsp_p_const_static_t) * patch->const_count)) < 0) { free(consts); return err; } free(consts); } return 0; } int ld10k1_fnc_send_patch_sta(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_p_const_static_t *stas = NULL; if (patch->sta_count) { stas = (ld10k1_dsp_p_const_static_t *)malloc(sizeof(ld10k1_dsp_p_const_static_t) * patch->sta_count); if (!stas) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->sta_count; i++) stas[i].const_val = patch->stas[i].const_val; if ((err = send_response(data_conn, FNC_CONTINUE, 0, stas, sizeof(ld10k1_dsp_p_const_static_t) * patch->sta_count)) < 0) { free(stas); return err; } free(stas); } return 0; } int ld10k1_fnc_send_patch_hw(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_p_hw_t *hws = NULL; if (patch->hw_count) { hws = (ld10k1_dsp_p_hw_t *)malloc(sizeof(ld10k1_dsp_p_hw_t) * patch->hw_count); if (!hws) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->hw_count; i++) hws[i].hw_val = patch->hws[i].reg_idx; if ((err = send_response(data_conn, FNC_CONTINUE, 0, hws, sizeof(ld10k1_dsp_p_hw_t) * patch->hw_count)) < 0) { free(hws); return err; } free(hws); } return 0; } int ld10k1_fnc_send_patch_tram_grp(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_tram_grp_t *grps = NULL; if (patch->tram_count) { grps = (ld10k1_dsp_tram_grp_t *)malloc(sizeof(ld10k1_dsp_tram_grp_t) * patch->tram_count); if (!grps) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->tram_count; i++) { grps[i].grp_type = patch->tram_grp[i].grp_type; grps[i].grp_size = patch->tram_grp[i].grp_size; grps[i].grp_pos = patch->tram_grp[i].grp_pos; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, grps, sizeof(ld10k1_dsp_tram_grp_t) * patch->tram_count)) < 0) { free(grps); return err; } free(grps); } return 0; } int ld10k1_fnc_send_patch_tram_acc(int data_conn, ld10k1_patch_t *patch) { int i, err; ld10k1_dsp_tram_acc_t *accs = NULL; if (patch->tram_acc_count) { accs = (ld10k1_dsp_tram_acc_t *)malloc(sizeof(ld10k1_dsp_tram_acc_t) * patch->tram_acc_count); if (!accs) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->tram_acc_count; i++) { accs[i].acc_type = patch->tram_acc[i].acc_type; accs[i].acc_offset = patch->tram_acc[i].acc_offset; accs[i].grp = patch->tram_acc[i].grp; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, accs, sizeof(ld10k1_dsp_tram_acc_t) * patch->tram_acc_count)) < 0) { free(accs); return err; } free(accs); } return 0; } int ld10k1_fnc_send_patch_ctl(int data_conn, ld10k1_patch_t *patch) { int i, j, err; ld10k1_dsp_ctl_t *ctls = NULL; if (patch->ctl_count) { ctls = (ld10k1_dsp_ctl_t *)malloc(sizeof(ld10k1_dsp_ctl_t) * patch->ctl_count); if (!ctls) return LD10K1_ERR_NO_MEM; memset(ctls, 0, sizeof(ld10k1_dsp_ctl_t) * patch->ctl_count); for (i = 0; i < patch->ctl_count; i++) { strncpy(ctls[i].name, patch->ctl[i].name, 43); ctls[i].name[43] = '\0'; ctls[i].index = patch->ctl[i].want_index; ctls[i].count = patch->ctl[i].count; ctls[i].vcount = patch->ctl[i].vcount; ctls[i].min = patch->ctl[i].min; ctls[i].max = patch->ctl[i].max; ctls[i].translation = patch->ctl[i].translation; for (j = 0; j < ctls[i].count; j++) ctls[i].value[j] = patch->ctl[i].value[j]; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, ctls, sizeof(ld10k1_dsp_ctl_t) * patch->ctl_count)) < 0) { free(ctls); return err; } free(ctls); } return 0; } int ld10k1_fnc_send_patch_instr(int data_conn, ld10k1_patch_t *patch) { int i, j, err; ld10k1_dsp_instr_t *instrs = NULL; if (patch->instr_count) { instrs = (ld10k1_dsp_instr_t *)malloc(sizeof(ld10k1_dsp_instr_t) * patch->instr_count); if (!instrs) return LD10K1_ERR_NO_MEM; for (i = 0; i < patch->instr_count; i++) { instrs[i].op_code = patch->instr[i].op_code; for (j = 0; j < 4; j++) instrs[i].arg[j] = patch->instr[i].arg[j]; } if ((err = send_response(data_conn, FNC_CONTINUE, 0, instrs, sizeof(ld10k1_dsp_instr_t) * patch->instr_count)) < 0) { free(instrs); return err; } free(instrs); } return 0; } int ld10k1_fnc_get_patch(int data_conn, int op, int size) { int err; ld10k1_dsp_patch_t patch_info; int patch_num = -1; ld10k1_patch_t *patch; if ((err = receive_msg_data(data_conn, &patch_num, sizeof(patch_num))) < 0) return err; if (dsp_mgr.patch_count >= 0) { if (patch_num > EMU10K1_PATCH_MAX) return LD10K1_ERR_UNKNOWN_PATCH_NUM; patch = dsp_mgr.patch_ptr[patch_num]; if (!patch) return LD10K1_ERR_UNKNOWN_PATCH_NUM; strcpy(patch_info.patch_name, patch->patch_name); patch_info.id = patch->id; patch_info.in_count = patch->in_count; patch_info.out_count = patch->out_count; patch_info.const_count = patch->const_count; patch_info.static_count = patch->sta_count; patch_info.dynamic_count = patch->dyn_count; patch_info.hw_count = patch->hw_count; patch_info.tram_count = patch->tram_count; patch_info.tram_acc_count = patch->tram_acc_count; patch_info.ctl_count = patch->ctl_count; patch_info.instr_count = patch->instr_count; if ((err = send_response(data_conn, FNC_CONTINUE, 0, &patch_info, sizeof(ld10k1_dsp_patch_t))) < 0) return err; /* send next parts */ if ((err = ld10k1_fnc_send_patch_in(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_out(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_const(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_sta(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_hw(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_tram_grp(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_tram_acc(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_ctl(data_conn, patch)) < 0) return err; if ((err = ld10k1_fnc_send_patch_instr(data_conn, patch)) < 0) return err; } return 0; } int ld10k1_fnc_dump(int data_conn, int op, int size) { int err; void *dump = NULL; int dump_size = 0; if ((err = ld10k1_make_dump(&dsp_mgr, &dump, &dump_size)) < 0) return err; if ((err = send_response(data_conn, FNC_CONTINUE, 0, dump, dump_size)) < 0) return err; free(dump); return 0; } int ld10k1_fnc_get_points_info(int data_conn, int op, int size) { int point_count; int i, j = 0; int *info = NULL; ld10k1_conn_point_t *point; point_count = 0; for (i = 0; i < 2; i++) { if (i) { if (!point_count) break; info = (int *)malloc(sizeof(int) * point_count); if (!info) return LD10K1_ERR_NO_MEM; j = 0; } point = dsp_mgr.point_list; while (point) { if (!i) point_count++; else info[j++] = point->id; point = point->next; } } return send_response_wd(data_conn, info, sizeof(int) * point_count); } int ld10k1_fnc_get_point_info(int data_conn, int op, int size) { int err; int k, l; ld10k1_dsp_point_t info; ld10k1_conn_point_t *point; ld10k1_conn_point_t *found_point; int what_point_id; /*info = NULL;*/ if ((err = receive_msg_data(data_conn, &what_point_id, sizeof(int))) < 0) return err; found_point = NULL; point = dsp_mgr.point_list; while (point) { if (point->id == what_point_id) { found_point = point; break; } point = point->next; } if (!found_point) return LD10K1_ERR_UNKNOWN_POINT; info.id = point->id; if (EMU10K1_REG_TYPE_B(point->con_gpr_idx) == EMU10K1_REG_TYPE_NORMAL) info.type = CON_IO_NORMAL; else if (EMU10K1_REG_TYPE_B(point->con_gpr_idx) == EMU10K1_REG_TYPE_INPUT) info.type = CON_IO_IN; else if (EMU10K1_REG_TYPE_B(point->con_gpr_idx) == EMU10K1_REG_TYPE_OUTPUT) info.type = CON_IO_OUT; else if (EMU10K1_REG_TYPE_B(point->con_gpr_idx) == EMU10K1_REG_TYPE_FX) info.type = CON_IO_FX; info.io_idx = point->con_gpr_idx & ~EMU10K1_REG_TYPE_MASK; info.simple = point->simple; info.conn_count = point->con_count; if (info.conn_count > 2 && info.type == CON_IO_NORMAL) info.multi = 1; else if (info.conn_count > 1 && info.type != CON_IO_NORMAL) info.multi = 1; else info.multi = 0; for (k = 0, l = 0; k < POINT_MAX_CONN_PER_POINT; k++) { if (point->type[k]) { info.io_type[l] = point->type[k] == CON_IO_PIN ? 0 : 1; info.patch[l] = point->patch[k] ? point->patch[k]->id : -1; info.io[l] = point->io[k]; l++; } } return send_response_wd(data_conn, &info, sizeof(ld10k1_dsp_point_t)); } int ld10k1_fnc_get_dsp_info(int data_conn, int op, int size) { ld10k1_fnc_dsp_info_t info; info.chip_type = dsp_mgr.audigy; return send_response_wd(data_conn, &info, sizeof(ld10k1_fnc_dsp_info_t)); }