17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
23*6d22b733Sdhain * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <strings.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #include <sys/mman.h>
377c478bd9Sstevel@tonic-gate #include <sys/pci.h>
387c478bd9Sstevel@tonic-gate #include <sys/stat.h>
397c478bd9Sstevel@tonic-gate #include <sys/wait.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include <fcode/private.h>
427c478bd9Sstevel@tonic-gate #include <fcode/log.h>
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate #include <fcdriver/fcdriver.h>
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate static char *pkg_my_args;
477c478bd9Sstevel@tonic-gate static char fcode_dev[] = "/dev/fcode";
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate static void
dot_request(fcode_env_t * env)507c478bd9Sstevel@tonic-gate dot_request(fcode_env_t *env)
517c478bd9Sstevel@tonic-gate {
527c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "request: cfgadd: %x fc_size: %x unitadd: %s"
557c478bd9Sstevel@tonic-gate " attach: %x args: '%s'\n", cdp->fc.config_address,
567c478bd9Sstevel@tonic-gate cdp->fc.fcode_size, cdp->fc.unit_address, cdp->attach,
577c478bd9Sstevel@tonic-gate pkg_my_args ? pkg_my_args : "<null>");
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate * Get next request from /dev/fcode.
627c478bd9Sstevel@tonic-gate */
637c478bd9Sstevel@tonic-gate int
fc_get_request(common_data_t * cdp)647c478bd9Sstevel@tonic-gate fc_get_request(common_data_t *cdp)
657c478bd9Sstevel@tonic-gate {
667c478bd9Sstevel@tonic-gate char c;
677c478bd9Sstevel@tonic-gate int nbytes;
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate if (cdp->fcode_fd < 0) {
707c478bd9Sstevel@tonic-gate log_message(MSG_FATAL, "fc_get_request: fcode_fd not open\n");
717c478bd9Sstevel@tonic-gate return (0);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate if ((nbytes = read(cdp->fcode_fd, &c, sizeof (c))) < 0) {
757c478bd9Sstevel@tonic-gate log_perror(MSG_FATAL, "read(%s) failed", fcode_dev);
767c478bd9Sstevel@tonic-gate return (0);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_PARAMETERS, &cdp->fc) < 0) {
807c478bd9Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_PARAMETERS) failed");
817c478bd9Sstevel@tonic-gate return (0);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate if ((cdp->attach = fc_get_ap(cdp)) == NULL)
857c478bd9Sstevel@tonic-gate return (0);
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate return (1);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate static void
get_my_args(fcode_env_t * env)917c478bd9Sstevel@tonic-gate get_my_args(fcode_env_t *env)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
947c478bd9Sstevel@tonic-gate char buffer[BUFSIZ];
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate * Don't get if already set.
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate if (pkg_my_args)
1007c478bd9Sstevel@tonic-gate return;
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_MY_ARGS, buffer) < 0) {
1037c478bd9Sstevel@tonic-gate return;
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate pkg_my_args = STRDUP(buffer);
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate static void
set_my_args(fcode_env_t * env)1097c478bd9Sstevel@tonic-gate set_my_args(fcode_env_t *env)
1107c478bd9Sstevel@tonic-gate {
1117c478bd9Sstevel@tonic-gate if (pkg_my_args)
1127c478bd9Sstevel@tonic-gate FREE(pkg_my_args);
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate parse_word(env);
1157c478bd9Sstevel@tonic-gate pkg_my_args = pop_a_duped_string(env, NULL);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate static void
dot_my_args(fcode_env_t * env)1197c478bd9Sstevel@tonic-gate dot_my_args(fcode_env_t *env)
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate if (pkg_my_args)
1227c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s\n", pkg_my_args);
1237c478bd9Sstevel@tonic-gate else
1247c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "NULL\n");
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate void
push_my_args(fcode_env_t * env)1287c478bd9Sstevel@tonic-gate push_my_args(fcode_env_t *env)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate push_a_string(env, pkg_my_args);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate void
get_fcode_from_device(fcode_env_t * env)1347c478bd9Sstevel@tonic-gate get_fcode_from_device(fcode_env_t *env)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
1377c478bd9Sstevel@tonic-gate char *p, *buf;
1387c478bd9Sstevel@tonic-gate static char func_name[] = "get_fcode_from_device";
1397c478bd9Sstevel@tonic-gate fc_fcode_info_t fcode_info;
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate if (!cdp->fc.fcode_size) {
1427c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: Fcode zero length\n",
1437c478bd9Sstevel@tonic-gate func_name);
1447c478bd9Sstevel@tonic-gate push_a_string(env, NULL);
1457c478bd9Sstevel@tonic-gate return;
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate fcode_info.fcode_size = cdp->fc.fcode_size;
1487c478bd9Sstevel@tonic-gate fcode_info.fcode_ptr = MALLOC(cdp->fc.fcode_size);
1497c478bd9Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_FCODE_DATA, &fcode_info) < 0) {
1507c478bd9Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_FCODE_DATA) failed");
1517c478bd9Sstevel@tonic-gate push_a_string(env, NULL);
1527c478bd9Sstevel@tonic-gate } else {
1537c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE,
1547c478bd9Sstevel@tonic-gate "%s: Fcode from device: len: 0x%x\n", func_name,
1557c478bd9Sstevel@tonic-gate (int)cdp->fc.fcode_size);
1567c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)fcode_info.fcode_ptr);
1577c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)cdp->fc.fcode_size);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate static void
save_fcode_to_file(fcode_env_t * env)1627c478bd9Sstevel@tonic-gate save_fcode_to_file(fcode_env_t *env)
1637c478bd9Sstevel@tonic-gate {
1647c478bd9Sstevel@tonic-gate char *buf, *fname;
1657c478bd9Sstevel@tonic-gate int len;
1667c478bd9Sstevel@tonic-gate FILE *fd;
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 4, "save-fcode-to-file");
1697c478bd9Sstevel@tonic-gate if ((fname = pop_a_string(env, NULL)) == NULL) {
1707c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "fname?\n");
1717c478bd9Sstevel@tonic-gate return;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate if ((buf = pop_a_string(env, &len)) == NULL) {
1747c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "buf?\n");
1757c478bd9Sstevel@tonic-gate return;
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate if ((fd = fopen(fname, "w")) == NULL) {
1787c478bd9Sstevel@tonic-gate log_perror(MSG_DEBUG, "Save_fcode_to_file: Can't open '%s'",
1797c478bd9Sstevel@tonic-gate fname);
1807c478bd9Sstevel@tonic-gate return;
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Fcode %p,%x to file '%s'\n", buf, len, fname);
1837c478bd9Sstevel@tonic-gate fwrite(buf, len, sizeof (char), fd);
1847c478bd9Sstevel@tonic-gate fclose(fd);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate void
exec_fcode_builtin_method(fcode_env_t * env)1887c478bd9Sstevel@tonic-gate exec_fcode_builtin_method(fcode_env_t *env)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate fstack_t d;
1917c478bd9Sstevel@tonic-gate char *method;
1927c478bd9Sstevel@tonic-gate extern void exec_parent_method(fcode_env_t *);
1937c478bd9Sstevel@tonic-gate extern void exec_builtin_driver(fcode_env_t *);
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate method = (char *)DS[-1];
1967c478bd9Sstevel@tonic-gate exec_parent_method(env);
1977c478bd9Sstevel@tonic-gate d = POP(DS);
1987c478bd9Sstevel@tonic-gate if (d) {
1997c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver: %s -> %s found\n",
2007c478bd9Sstevel@tonic-gate method, (char *)DS[-1]);
2017c478bd9Sstevel@tonic-gate exec_builtin_driver(env);
2027c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver-exec: %p %x\n",
2037c478bd9Sstevel@tonic-gate (char *)DS[-1], (int)TOS);
2047c478bd9Sstevel@tonic-gate } else {
2057c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver: %s not found\n",
2067c478bd9Sstevel@tonic-gate method);
2077c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate void
get_fcode_from_filesystem(fcode_env_t * env)2127c478bd9Sstevel@tonic-gate get_fcode_from_filesystem(fcode_env_t *env)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate fstack_t d;
2157c478bd9Sstevel@tonic-gate char *method, *fc_name, *path;
2167c478bd9Sstevel@tonic-gate extern void exec_parent_method(fcode_env_t *);
2177c478bd9Sstevel@tonic-gate static char fname[] = "get-fcode-from-filesystem";
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate method = (char *)DS[-1];
2207c478bd9Sstevel@tonic-gate exec_parent_method(env);
2217c478bd9Sstevel@tonic-gate d = POP(DS);
2227c478bd9Sstevel@tonic-gate if (d) {
2237c478bd9Sstevel@tonic-gate fc_name = pop_a_string(env, NULL);
2247c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: %s -> %s found\n", fname,
2257c478bd9Sstevel@tonic-gate method, fc_name);
2267c478bd9Sstevel@tonic-gate if ((path = search_for_fcode_file(env, fc_name)) != NULL) {
2277c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: file: %s FOUND\n",
2287c478bd9Sstevel@tonic-gate fname, path);
2297c478bd9Sstevel@tonic-gate push_a_string(env, path);
2307c478bd9Sstevel@tonic-gate load_file(env);
2317c478bd9Sstevel@tonic-gate } else {
2327c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: file '%s' not found\n",
2337c478bd9Sstevel@tonic-gate fname, fc_name);
2347c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate } else {
2377c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: method '%s' not found\n",
2387c478bd9Sstevel@tonic-gate fname, method);
2397c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate /*
2447c478bd9Sstevel@tonic-gate * Looks for "device-id" and "class-id" methods in parent, if there,
2457c478bd9Sstevel@tonic-gate * executes them to get "builtin drivers" file name or method name, then
2467c478bd9Sstevel@tonic-gate * executes the builtin-driver method. If both those fail, try getting the
2477c478bd9Sstevel@tonic-gate * fcode from the device. Note that we sleaze resetting the data stack.
2487c478bd9Sstevel@tonic-gate * This would be cleaner if we had a way to do the equivalent of "catch/throw"
2497c478bd9Sstevel@tonic-gate * from within C code.
2507c478bd9Sstevel@tonic-gate */
2517c478bd9Sstevel@tonic-gate void
find_fcode(fcode_env_t * env)2527c478bd9Sstevel@tonic-gate find_fcode(fcode_env_t *env)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate fstack_t *dp = env->ds;
255*6d22b733Sdhain common_data_t *cdp = env->private;
2567c478bd9Sstevel@tonic-gate static char func_name[] = "find_fcode";
257*6d22b733Sdhain int error;
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate my_unit(env);
2607c478bd9Sstevel@tonic-gate push_a_string(env, "device-id");
2617c478bd9Sstevel@tonic-gate get_fcode_from_filesystem(env);
2627c478bd9Sstevel@tonic-gate if (TOS) {
2637c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: FS dev-id: len: 0x%x\n",
2647c478bd9Sstevel@tonic-gate func_name, TOS);
2657c478bd9Sstevel@tonic-gate return;
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate env->ds = dp;
2697c478bd9Sstevel@tonic-gate my_unit(env);
2707c478bd9Sstevel@tonic-gate push_a_string(env, "class-id");
2717c478bd9Sstevel@tonic-gate get_fcode_from_filesystem(env);
2727c478bd9Sstevel@tonic-gate if (TOS) {
2737c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: FS cls-id len: 0x%x\n",
2747c478bd9Sstevel@tonic-gate func_name, TOS);
2757c478bd9Sstevel@tonic-gate return;
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate env->ds = dp;
2797c478bd9Sstevel@tonic-gate get_fcode_from_device(env);
2807c478bd9Sstevel@tonic-gate if (TOS) {
2817c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: DEV fcode len: 0x%x\n",
2827c478bd9Sstevel@tonic-gate func_name, TOS);
2837c478bd9Sstevel@tonic-gate return;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate env->ds = dp;
2877c478bd9Sstevel@tonic-gate my_unit(env);
2887c478bd9Sstevel@tonic-gate push_a_string(env, "device-id");
2897c478bd9Sstevel@tonic-gate exec_fcode_builtin_method(env);
2907c478bd9Sstevel@tonic-gate if (TOS) {
2917c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: dropin dev-id len: 0x%x\n",
2927c478bd9Sstevel@tonic-gate func_name, TOS);
2937c478bd9Sstevel@tonic-gate return;
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate env->ds = dp;
2977c478bd9Sstevel@tonic-gate my_unit(env);
2987c478bd9Sstevel@tonic-gate push_a_string(env, "class-id");
2997c478bd9Sstevel@tonic-gate exec_fcode_builtin_method(env);
3007c478bd9Sstevel@tonic-gate if (TOS) {
3017c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: dropin cls-id len: 0x%x\n",
3027c478bd9Sstevel@tonic-gate func_name, TOS);
3037c478bd9Sstevel@tonic-gate return;
3047c478bd9Sstevel@tonic-gate }
305*6d22b733Sdhain
3067c478bd9Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: not found\n", func_name);
307*6d22b733Sdhain error = FC_NO_FCODE;
308*6d22b733Sdhain if (ioctl(cdp->fcode_fd, FC_SET_FCODE_ERROR, &error) < 0) {
309*6d22b733Sdhain log_perror(MSG_FATAL, "ioctl(FC_SET_FCODE_ERROR) failed");
310*6d22b733Sdhain return;
311*6d22b733Sdhain }
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate int
open_fcode_dev(fcode_env_t * env)3157c478bd9Sstevel@tonic-gate open_fcode_dev(fcode_env_t *env)
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate if ((cdp->fcode_fd = open(fcode_dev, O_RDONLY)) < 0)
3207c478bd9Sstevel@tonic-gate log_perror(MSG_ERROR, "Can't open '%s'", fcode_dev);
3217c478bd9Sstevel@tonic-gate return (cdp->fcode_fd >= 0);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate static void
get_request(fcode_env_t * env)3257c478bd9Sstevel@tonic-gate get_request(fcode_env_t *env)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate if (cdp->fcode_fd >= 0)
3307c478bd9Sstevel@tonic-gate close(cdp->fcode_fd);
3317c478bd9Sstevel@tonic-gate if (!open_fcode_dev(env))
3327c478bd9Sstevel@tonic-gate exit(1);
3337c478bd9Sstevel@tonic-gate if (!fc_get_request(cdp)) {
3347c478bd9Sstevel@tonic-gate log_message(MSG_FATAL, "fc_get_request failed\n");
3357c478bd9Sstevel@tonic-gate exit(1);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate get_my_args(env);
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate DEBUGF(UPLOAD, dot_request(env));
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate /*
3447c478bd9Sstevel@tonic-gate * invoked from efdaemon, /dev/fcode event has been read and /dev/fcode opened
3457c478bd9Sstevel@tonic-gate * file descriptor is fd 0.
3467c478bd9Sstevel@tonic-gate */
3477c478bd9Sstevel@tonic-gate static void
get_efdaemon_request(fcode_env_t * env)3487c478bd9Sstevel@tonic-gate get_efdaemon_request(fcode_env_t *env)
3497c478bd9Sstevel@tonic-gate {
3507c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate cdp->fcode_fd = 0;
3537c478bd9Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_PARAMETERS, &cdp->fc) < 0) {
3547c478bd9Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_PARAMETERS) failed");
3557c478bd9Sstevel@tonic-gate exit(1);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate if ((cdp->attach = fc_get_ap(cdp)) == NULL)
3597c478bd9Sstevel@tonic-gate exit(1);
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate get_my_args(env);
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate DEBUGF(UPLOAD, dot_request(env));
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate static void
process_request(fcode_env_t * env)3677c478bd9Sstevel@tonic-gate process_request(fcode_env_t *env)
3687c478bd9Sstevel@tonic-gate {
3697c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
3707c478bd9Sstevel@tonic-gate fstack_t fcode_len;
3717c478bd9Sstevel@tonic-gate char *path;
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate build_tree(env);
3747c478bd9Sstevel@tonic-gate install_builtin_nodes(env);
3757c478bd9Sstevel@tonic-gate push_my_args(env);
3767c478bd9Sstevel@tonic-gate push_a_string(env, cdp->fc.unit_address);
3777c478bd9Sstevel@tonic-gate if ((path = get_path(env, env->attachment_pt)) == NULL) {
3787c478bd9Sstevel@tonic-gate log_message(MSG_FATAL, "Can't get_path of"
3797c478bd9Sstevel@tonic-gate " attachment_pt %p\n", env->attachment_pt);
3807c478bd9Sstevel@tonic-gate exit(1);
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Attach Point: %s\n", path);
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate push_a_string(env, path);
3857c478bd9Sstevel@tonic-gate begin_package(env);
3867c478bd9Sstevel@tonic-gate find_fcode(env);
3877c478bd9Sstevel@tonic-gate fcode_len = POP(DS);
3887c478bd9Sstevel@tonic-gate if (!fcode_len) {
3897c478bd9Sstevel@tonic-gate (void) POP(DS);
3907c478bd9Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Zero length Fcode\n");
3917c478bd9Sstevel@tonic-gate return;
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "byte-load fcode_len: %x\n",
3957c478bd9Sstevel@tonic-gate fcode_len);
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate PUSH(DS, 1);
3987c478bd9Sstevel@tonic-gate byte_load(env);
3997c478bd9Sstevel@tonic-gate end_package(env);
4007c478bd9Sstevel@tonic-gate upload_nodes(env);
4017c478bd9Sstevel@tonic-gate validate_nodes(env);
4027c478bd9Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Upload Done\n");
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate static void
finish_request(fcode_env_t * env)4067c478bd9Sstevel@tonic-gate finish_request(fcode_env_t *env)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate common_data_t *cdp = env->private;
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate close(cdp->fcode_fd);
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate /*
4147c478bd9Sstevel@tonic-gate * Non-daemon "do-request", for debugging
4157c478bd9Sstevel@tonic-gate */
4167c478bd9Sstevel@tonic-gate static void
do_request(fcode_env_t * env)4177c478bd9Sstevel@tonic-gate do_request(fcode_env_t *env)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate get_request(env);
4207c478bd9Sstevel@tonic-gate process_request(env);
4217c478bd9Sstevel@tonic-gate finish_request(env);
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate
4247c478bd9Sstevel@tonic-gate /*
4257c478bd9Sstevel@tonic-gate * This process one request from efdaemon, we know that /dev/fcode is already
4267c478bd9Sstevel@tonic-gate * open and passed in fd0 (stdin). If it's not, we throw up our hands.
4277c478bd9Sstevel@tonic-gate */
4287c478bd9Sstevel@tonic-gate void
run_one_efdaemon_request(fcode_env_t * env)4297c478bd9Sstevel@tonic-gate run_one_efdaemon_request(fcode_env_t *env)
4307c478bd9Sstevel@tonic-gate {
4317c478bd9Sstevel@tonic-gate get_efdaemon_request(env);
4327c478bd9Sstevel@tonic-gate process_request(env);
4337c478bd9Sstevel@tonic-gate finish_request(env);
4347c478bd9Sstevel@tonic-gate exit(0);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate void
probe_space(fcode_env_t * env)4387c478bd9Sstevel@tonic-gate probe_space(fcode_env_t *env)
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate fc_cell_t cfg = 0;
4417c478bd9Sstevel@tonic-gate int error;
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate error = fc_run_priv(env->private, FC_PROBE_SPACE, 0, 1, &cfg);
4447c478bd9Sstevel@tonic-gate if (error)
4457c478bd9Sstevel@tonic-gate throw_from_fclib(env, 1, "FC_PROBE_SPACE failed\n");
4467c478bd9Sstevel@tonic-gate PUSH(DS, fc_cell2uint32_t(cfg));
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate #pragma init(_init)
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate static void
_init(void)4527c478bd9Sstevel@tonic-gate _init(void)
4537c478bd9Sstevel@tonic-gate {
4547c478bd9Sstevel@tonic-gate fcode_env_t *env = initial_env;
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate ASSERT(env);
4577c478bd9Sstevel@tonic-gate NOTICE;
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate FORTH(0, "get-fcode-from-device", get_fcode_from_device);
4607c478bd9Sstevel@tonic-gate FORTH(0, "save-fcode-to-file", save_fcode_to_file);
4617c478bd9Sstevel@tonic-gate FORTH(0, "get-my-args", get_my_args);
4627c478bd9Sstevel@tonic-gate FORTH(0, "set-my-args", set_my_args);
4637c478bd9Sstevel@tonic-gate FORTH(0, ".my-args", dot_my_args);
4647c478bd9Sstevel@tonic-gate FORTH(0, ".request", dot_request);
4657c478bd9Sstevel@tonic-gate FORTH(0, "get-request", get_request);
4667c478bd9Sstevel@tonic-gate FORTH(0, "process-request", process_request);
4677c478bd9Sstevel@tonic-gate FORTH(0, "finish-request", finish_request);
4687c478bd9Sstevel@tonic-gate FORTH(0, "do-request", do_request);
4697c478bd9Sstevel@tonic-gate FORTH(0, "find-fcode", find_fcode);
4707c478bd9Sstevel@tonic-gate FORTH(0, "exec-fcode-builtin-method", exec_fcode_builtin_method);
4717c478bd9Sstevel@tonic-gate FORTH(0, "run-one-efdaemon-request", run_one_efdaemon_request);
4727c478bd9Sstevel@tonic-gate FORTH(0, "get-efdaemon-request", get_efdaemon_request);
4737c478bd9Sstevel@tonic-gate FORTH(0, "probe-space", probe_space);
4747c478bd9Sstevel@tonic-gate }
475