10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*762Sdhain * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <fcntl.h>
300Sstevel@tonic-gate #include <unistd.h>
310Sstevel@tonic-gate #include <stdlib.h>
320Sstevel@tonic-gate #include <stdio.h>
330Sstevel@tonic-gate #include <strings.h>
340Sstevel@tonic-gate #include <errno.h>
350Sstevel@tonic-gate
360Sstevel@tonic-gate #include <sys/mman.h>
370Sstevel@tonic-gate #include <sys/pci.h>
380Sstevel@tonic-gate #include <sys/stat.h>
390Sstevel@tonic-gate #include <sys/wait.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate #include <fcode/private.h>
420Sstevel@tonic-gate #include <fcode/log.h>
430Sstevel@tonic-gate
440Sstevel@tonic-gate #include <fcdriver/fcdriver.h>
450Sstevel@tonic-gate
460Sstevel@tonic-gate static char *pkg_my_args;
470Sstevel@tonic-gate static char fcode_dev[] = "/dev/fcode";
480Sstevel@tonic-gate
490Sstevel@tonic-gate static void
dot_request(fcode_env_t * env)500Sstevel@tonic-gate dot_request(fcode_env_t *env)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate common_data_t *cdp = env->private;
530Sstevel@tonic-gate
540Sstevel@tonic-gate log_message(MSG_INFO, "request: cfgadd: %x fc_size: %x unitadd: %s"
550Sstevel@tonic-gate " attach: %x args: '%s'\n", cdp->fc.config_address,
560Sstevel@tonic-gate cdp->fc.fcode_size, cdp->fc.unit_address, cdp->attach,
570Sstevel@tonic-gate pkg_my_args ? pkg_my_args : "<null>");
580Sstevel@tonic-gate }
590Sstevel@tonic-gate
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * Get next request from /dev/fcode.
620Sstevel@tonic-gate */
630Sstevel@tonic-gate int
fc_get_request(common_data_t * cdp)640Sstevel@tonic-gate fc_get_request(common_data_t *cdp)
650Sstevel@tonic-gate {
660Sstevel@tonic-gate char c;
670Sstevel@tonic-gate int nbytes;
680Sstevel@tonic-gate
690Sstevel@tonic-gate if (cdp->fcode_fd < 0) {
700Sstevel@tonic-gate log_message(MSG_FATAL, "fc_get_request: fcode_fd not open\n");
710Sstevel@tonic-gate return (0);
720Sstevel@tonic-gate }
730Sstevel@tonic-gate
740Sstevel@tonic-gate if ((nbytes = read(cdp->fcode_fd, &c, sizeof (c))) < 0) {
750Sstevel@tonic-gate log_perror(MSG_FATAL, "read(%s) failed", fcode_dev);
760Sstevel@tonic-gate return (0);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_PARAMETERS, &cdp->fc) < 0) {
800Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_PARAMETERS) failed");
810Sstevel@tonic-gate return (0);
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
840Sstevel@tonic-gate if ((cdp->attach = fc_get_ap(cdp)) == NULL)
850Sstevel@tonic-gate return (0);
860Sstevel@tonic-gate
870Sstevel@tonic-gate return (1);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate static void
get_my_args(fcode_env_t * env)910Sstevel@tonic-gate get_my_args(fcode_env_t *env)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate common_data_t *cdp = env->private;
940Sstevel@tonic-gate char buffer[BUFSIZ];
950Sstevel@tonic-gate
960Sstevel@tonic-gate /*
970Sstevel@tonic-gate * Don't get if already set.
980Sstevel@tonic-gate */
990Sstevel@tonic-gate if (pkg_my_args)
1000Sstevel@tonic-gate return;
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_MY_ARGS, buffer) < 0) {
1030Sstevel@tonic-gate return;
1040Sstevel@tonic-gate }
1050Sstevel@tonic-gate pkg_my_args = STRDUP(buffer);
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate static void
set_my_args(fcode_env_t * env)1090Sstevel@tonic-gate set_my_args(fcode_env_t *env)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate if (pkg_my_args)
1120Sstevel@tonic-gate FREE(pkg_my_args);
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate parse_word(env);
1150Sstevel@tonic-gate pkg_my_args = pop_a_duped_string(env, NULL);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate static void
dot_my_args(fcode_env_t * env)1190Sstevel@tonic-gate dot_my_args(fcode_env_t *env)
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate if (pkg_my_args)
1220Sstevel@tonic-gate log_message(MSG_INFO, "%s\n", pkg_my_args);
1230Sstevel@tonic-gate else
1240Sstevel@tonic-gate log_message(MSG_INFO, "NULL\n");
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate void
push_my_args(fcode_env_t * env)1280Sstevel@tonic-gate push_my_args(fcode_env_t *env)
1290Sstevel@tonic-gate {
1300Sstevel@tonic-gate push_a_string(env, pkg_my_args);
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate void
get_fcode_from_device(fcode_env_t * env)1340Sstevel@tonic-gate get_fcode_from_device(fcode_env_t *env)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate common_data_t *cdp = env->private;
1370Sstevel@tonic-gate char *p, *buf;
1380Sstevel@tonic-gate static char func_name[] = "get_fcode_from_device";
1390Sstevel@tonic-gate fc_fcode_info_t fcode_info;
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate if (!cdp->fc.fcode_size) {
1420Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: Fcode zero length\n",
1430Sstevel@tonic-gate func_name);
1440Sstevel@tonic-gate push_a_string(env, NULL);
1450Sstevel@tonic-gate return;
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate fcode_info.fcode_size = cdp->fc.fcode_size;
1480Sstevel@tonic-gate fcode_info.fcode_ptr = MALLOC(cdp->fc.fcode_size);
1490Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_FCODE_DATA, &fcode_info) < 0) {
1500Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_FCODE_DATA) failed");
1510Sstevel@tonic-gate push_a_string(env, NULL);
1520Sstevel@tonic-gate } else {
1530Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE,
1540Sstevel@tonic-gate "%s: Fcode from device: len: 0x%x\n", func_name,
1550Sstevel@tonic-gate (int)cdp->fc.fcode_size);
1560Sstevel@tonic-gate PUSH(DS, (fstack_t)fcode_info.fcode_ptr);
1570Sstevel@tonic-gate PUSH(DS, (fstack_t)cdp->fc.fcode_size);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate static void
save_fcode_to_file(fcode_env_t * env)1620Sstevel@tonic-gate save_fcode_to_file(fcode_env_t *env)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate char *buf, *fname;
1650Sstevel@tonic-gate int len;
1660Sstevel@tonic-gate FILE *fd;
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate CHECK_DEPTH(env, 4, "save-fcode-to-file");
1690Sstevel@tonic-gate if ((fname = pop_a_string(env, NULL)) == NULL) {
1700Sstevel@tonic-gate log_message(MSG_DEBUG, "fname?\n");
1710Sstevel@tonic-gate return;
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate if ((buf = pop_a_string(env, &len)) == NULL) {
1740Sstevel@tonic-gate log_message(MSG_INFO, "buf?\n");
1750Sstevel@tonic-gate return;
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate if ((fd = fopen(fname, "w")) == NULL) {
1780Sstevel@tonic-gate log_perror(MSG_DEBUG, "Save_fcode_to_file: Can't open '%s'",
1790Sstevel@tonic-gate fname);
1800Sstevel@tonic-gate return;
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate log_message(MSG_INFO, "Fcode %p,%x to file '%s'\n", buf, len, fname);
1830Sstevel@tonic-gate fwrite(buf, len, sizeof (char), fd);
1840Sstevel@tonic-gate fclose(fd);
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate void
exec_fcode_builtin_method(fcode_env_t * env)1880Sstevel@tonic-gate exec_fcode_builtin_method(fcode_env_t *env)
1890Sstevel@tonic-gate {
1900Sstevel@tonic-gate fstack_t d;
1910Sstevel@tonic-gate char *method;
1920Sstevel@tonic-gate extern void exec_parent_method(fcode_env_t *);
1930Sstevel@tonic-gate extern void exec_builtin_driver(fcode_env_t *);
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate method = (char *)DS[-1];
1960Sstevel@tonic-gate exec_parent_method(env);
1970Sstevel@tonic-gate d = POP(DS);
1980Sstevel@tonic-gate if (d) {
1990Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver: %s -> %s found\n",
2000Sstevel@tonic-gate method, (char *)DS[-1]);
2010Sstevel@tonic-gate exec_builtin_driver(env);
2020Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver-exec: %p %x\n",
2030Sstevel@tonic-gate (char *)DS[-1], (int)TOS);
2040Sstevel@tonic-gate } else {
2050Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "builtin-driver: %s not found\n",
2060Sstevel@tonic-gate method);
2070Sstevel@tonic-gate PUSH(DS, FALSE);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate void
get_fcode_from_filesystem(fcode_env_t * env)2120Sstevel@tonic-gate get_fcode_from_filesystem(fcode_env_t *env)
2130Sstevel@tonic-gate {
2140Sstevel@tonic-gate fstack_t d;
2150Sstevel@tonic-gate char *method, *fc_name, *path;
2160Sstevel@tonic-gate extern void exec_parent_method(fcode_env_t *);
2170Sstevel@tonic-gate static char fname[] = "get-fcode-from-filesystem";
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate method = (char *)DS[-1];
2200Sstevel@tonic-gate exec_parent_method(env);
2210Sstevel@tonic-gate d = POP(DS);
2220Sstevel@tonic-gate if (d) {
2230Sstevel@tonic-gate fc_name = pop_a_string(env, NULL);
2240Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: %s -> %s found\n", fname,
2250Sstevel@tonic-gate method, fc_name);
2260Sstevel@tonic-gate if ((path = search_for_fcode_file(env, fc_name)) != NULL) {
2270Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: file: %s FOUND\n",
2280Sstevel@tonic-gate fname, path);
2290Sstevel@tonic-gate push_a_string(env, path);
2300Sstevel@tonic-gate load_file(env);
2310Sstevel@tonic-gate } else {
2320Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: file '%s' not found\n",
2330Sstevel@tonic-gate fname, fc_name);
2340Sstevel@tonic-gate PUSH(DS, FALSE);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate } else {
2370Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: method '%s' not found\n",
2380Sstevel@tonic-gate fname, method);
2390Sstevel@tonic-gate PUSH(DS, FALSE);
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate /*
2440Sstevel@tonic-gate * Looks for "device-id" and "class-id" methods in parent, if there,
2450Sstevel@tonic-gate * executes them to get "builtin drivers" file name or method name, then
2460Sstevel@tonic-gate * executes the builtin-driver method. If both those fail, try getting the
2470Sstevel@tonic-gate * fcode from the device. Note that we sleaze resetting the data stack.
2480Sstevel@tonic-gate * This would be cleaner if we had a way to do the equivalent of "catch/throw"
2490Sstevel@tonic-gate * from within C code.
2500Sstevel@tonic-gate */
2510Sstevel@tonic-gate void
find_fcode(fcode_env_t * env)2520Sstevel@tonic-gate find_fcode(fcode_env_t *env)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate fstack_t *dp = env->ds;
255*762Sdhain common_data_t *cdp = env->private;
2560Sstevel@tonic-gate static char func_name[] = "find_fcode";
257*762Sdhain int error;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate my_unit(env);
2600Sstevel@tonic-gate push_a_string(env, "device-id");
2610Sstevel@tonic-gate get_fcode_from_filesystem(env);
2620Sstevel@tonic-gate if (TOS) {
2630Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: FS dev-id: len: 0x%x\n",
2640Sstevel@tonic-gate func_name, TOS);
2650Sstevel@tonic-gate return;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate env->ds = dp;
2690Sstevel@tonic-gate my_unit(env);
2700Sstevel@tonic-gate push_a_string(env, "class-id");
2710Sstevel@tonic-gate get_fcode_from_filesystem(env);
2720Sstevel@tonic-gate if (TOS) {
2730Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: FS cls-id len: 0x%x\n",
2740Sstevel@tonic-gate func_name, TOS);
2750Sstevel@tonic-gate return;
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate env->ds = dp;
2790Sstevel@tonic-gate get_fcode_from_device(env);
2800Sstevel@tonic-gate if (TOS) {
2810Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: DEV fcode len: 0x%x\n",
2820Sstevel@tonic-gate func_name, TOS);
2830Sstevel@tonic-gate return;
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate env->ds = dp;
2870Sstevel@tonic-gate my_unit(env);
2880Sstevel@tonic-gate push_a_string(env, "device-id");
2890Sstevel@tonic-gate exec_fcode_builtin_method(env);
2900Sstevel@tonic-gate if (TOS) {
2910Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: dropin dev-id len: 0x%x\n",
2920Sstevel@tonic-gate func_name, TOS);
2930Sstevel@tonic-gate return;
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate env->ds = dp;
2970Sstevel@tonic-gate my_unit(env);
2980Sstevel@tonic-gate push_a_string(env, "class-id");
2990Sstevel@tonic-gate exec_fcode_builtin_method(env);
3000Sstevel@tonic-gate if (TOS) {
3010Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: dropin cls-id len: 0x%x\n",
3020Sstevel@tonic-gate func_name, TOS);
3030Sstevel@tonic-gate return;
3040Sstevel@tonic-gate }
305*762Sdhain
3060Sstevel@tonic-gate debug_msg(DEBUG_FIND_FCODE, "%s: not found\n", func_name);
307*762Sdhain error = FC_NO_FCODE;
308*762Sdhain if (ioctl(cdp->fcode_fd, FC_SET_FCODE_ERROR, &error) < 0) {
309*762Sdhain log_perror(MSG_FATAL, "ioctl(FC_SET_FCODE_ERROR) failed");
310*762Sdhain return;
311*762Sdhain }
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate int
open_fcode_dev(fcode_env_t * env)3150Sstevel@tonic-gate open_fcode_dev(fcode_env_t *env)
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate common_data_t *cdp = env->private;
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate if ((cdp->fcode_fd = open(fcode_dev, O_RDONLY)) < 0)
3200Sstevel@tonic-gate log_perror(MSG_ERROR, "Can't open '%s'", fcode_dev);
3210Sstevel@tonic-gate return (cdp->fcode_fd >= 0);
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate static void
get_request(fcode_env_t * env)3250Sstevel@tonic-gate get_request(fcode_env_t *env)
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate common_data_t *cdp = env->private;
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate if (cdp->fcode_fd >= 0)
3300Sstevel@tonic-gate close(cdp->fcode_fd);
3310Sstevel@tonic-gate if (!open_fcode_dev(env))
3320Sstevel@tonic-gate exit(1);
3330Sstevel@tonic-gate if (!fc_get_request(cdp)) {
3340Sstevel@tonic-gate log_message(MSG_FATAL, "fc_get_request failed\n");
3350Sstevel@tonic-gate exit(1);
3360Sstevel@tonic-gate }
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate get_my_args(env);
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate DEBUGF(UPLOAD, dot_request(env));
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate /*
3440Sstevel@tonic-gate * invoked from efdaemon, /dev/fcode event has been read and /dev/fcode opened
3450Sstevel@tonic-gate * file descriptor is fd 0.
3460Sstevel@tonic-gate */
3470Sstevel@tonic-gate static void
get_efdaemon_request(fcode_env_t * env)3480Sstevel@tonic-gate get_efdaemon_request(fcode_env_t *env)
3490Sstevel@tonic-gate {
3500Sstevel@tonic-gate common_data_t *cdp = env->private;
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate cdp->fcode_fd = 0;
3530Sstevel@tonic-gate if (ioctl(cdp->fcode_fd, FC_GET_PARAMETERS, &cdp->fc) < 0) {
3540Sstevel@tonic-gate log_perror(MSG_FATAL, "ioctl(FC_GET_PARAMETERS) failed");
3550Sstevel@tonic-gate exit(1);
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate if ((cdp->attach = fc_get_ap(cdp)) == NULL)
3590Sstevel@tonic-gate exit(1);
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate get_my_args(env);
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate DEBUGF(UPLOAD, dot_request(env));
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate static void
process_request(fcode_env_t * env)3670Sstevel@tonic-gate process_request(fcode_env_t *env)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate common_data_t *cdp = env->private;
3700Sstevel@tonic-gate fstack_t fcode_len;
3710Sstevel@tonic-gate char *path;
3720Sstevel@tonic-gate
3730Sstevel@tonic-gate build_tree(env);
3740Sstevel@tonic-gate install_builtin_nodes(env);
3750Sstevel@tonic-gate push_my_args(env);
3760Sstevel@tonic-gate push_a_string(env, cdp->fc.unit_address);
3770Sstevel@tonic-gate if ((path = get_path(env, env->attachment_pt)) == NULL) {
3780Sstevel@tonic-gate log_message(MSG_FATAL, "Can't get_path of"
3790Sstevel@tonic-gate " attachment_pt %p\n", env->attachment_pt);
3800Sstevel@tonic-gate exit(1);
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Attach Point: %s\n", path);
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate push_a_string(env, path);
3850Sstevel@tonic-gate begin_package(env);
3860Sstevel@tonic-gate find_fcode(env);
3870Sstevel@tonic-gate fcode_len = POP(DS);
3880Sstevel@tonic-gate if (!fcode_len) {
3890Sstevel@tonic-gate (void) POP(DS);
3900Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Zero length Fcode\n");
3910Sstevel@tonic-gate return;
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "byte-load fcode_len: %x\n",
3950Sstevel@tonic-gate fcode_len);
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate PUSH(DS, 1);
3980Sstevel@tonic-gate byte_load(env);
3990Sstevel@tonic-gate end_package(env);
4000Sstevel@tonic-gate upload_nodes(env);
4010Sstevel@tonic-gate validate_nodes(env);
4020Sstevel@tonic-gate debug_msg(DEBUG_UPLOAD, "Upload Done\n");
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate static void
finish_request(fcode_env_t * env)4060Sstevel@tonic-gate finish_request(fcode_env_t *env)
4070Sstevel@tonic-gate {
4080Sstevel@tonic-gate common_data_t *cdp = env->private;
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate close(cdp->fcode_fd);
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate * Non-daemon "do-request", for debugging
4150Sstevel@tonic-gate */
4160Sstevel@tonic-gate static void
do_request(fcode_env_t * env)4170Sstevel@tonic-gate do_request(fcode_env_t *env)
4180Sstevel@tonic-gate {
4190Sstevel@tonic-gate get_request(env);
4200Sstevel@tonic-gate process_request(env);
4210Sstevel@tonic-gate finish_request(env);
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate /*
4250Sstevel@tonic-gate * This process one request from efdaemon, we know that /dev/fcode is already
4260Sstevel@tonic-gate * open and passed in fd0 (stdin). If it's not, we throw up our hands.
4270Sstevel@tonic-gate */
4280Sstevel@tonic-gate void
run_one_efdaemon_request(fcode_env_t * env)4290Sstevel@tonic-gate run_one_efdaemon_request(fcode_env_t *env)
4300Sstevel@tonic-gate {
4310Sstevel@tonic-gate get_efdaemon_request(env);
4320Sstevel@tonic-gate process_request(env);
4330Sstevel@tonic-gate finish_request(env);
4340Sstevel@tonic-gate exit(0);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate void
probe_space(fcode_env_t * env)4380Sstevel@tonic-gate probe_space(fcode_env_t *env)
4390Sstevel@tonic-gate {
4400Sstevel@tonic-gate fc_cell_t cfg = 0;
4410Sstevel@tonic-gate int error;
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate error = fc_run_priv(env->private, FC_PROBE_SPACE, 0, 1, &cfg);
4440Sstevel@tonic-gate if (error)
4450Sstevel@tonic-gate throw_from_fclib(env, 1, "FC_PROBE_SPACE failed\n");
4460Sstevel@tonic-gate PUSH(DS, fc_cell2uint32_t(cfg));
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate #pragma init(_init)
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate static void
_init(void)4520Sstevel@tonic-gate _init(void)
4530Sstevel@tonic-gate {
4540Sstevel@tonic-gate fcode_env_t *env = initial_env;
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate ASSERT(env);
4570Sstevel@tonic-gate NOTICE;
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate FORTH(0, "get-fcode-from-device", get_fcode_from_device);
4600Sstevel@tonic-gate FORTH(0, "save-fcode-to-file", save_fcode_to_file);
4610Sstevel@tonic-gate FORTH(0, "get-my-args", get_my_args);
4620Sstevel@tonic-gate FORTH(0, "set-my-args", set_my_args);
4630Sstevel@tonic-gate FORTH(0, ".my-args", dot_my_args);
4640Sstevel@tonic-gate FORTH(0, ".request", dot_request);
4650Sstevel@tonic-gate FORTH(0, "get-request", get_request);
4660Sstevel@tonic-gate FORTH(0, "process-request", process_request);
4670Sstevel@tonic-gate FORTH(0, "finish-request", finish_request);
4680Sstevel@tonic-gate FORTH(0, "do-request", do_request);
4690Sstevel@tonic-gate FORTH(0, "find-fcode", find_fcode);
4700Sstevel@tonic-gate FORTH(0, "exec-fcode-builtin-method", exec_fcode_builtin_method);
4710Sstevel@tonic-gate FORTH(0, "run-one-efdaemon-request", run_one_efdaemon_request);
4720Sstevel@tonic-gate FORTH(0, "get-efdaemon-request", get_efdaemon_request);
4730Sstevel@tonic-gate FORTH(0, "probe-space", probe_space);
4740Sstevel@tonic-gate }
475