xref: /onnv-gate/usr/src/lib/efcode/fcdriver/get_req.c (revision 762:bac9c2e4aa76)
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