xref: /titanic_52/usr/src/lib/efcode/fcdriver/get_req.c (revision 6d22b73346a02763769401e9f28b596670cc3d16)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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