xref: /onnv-gate/usr/src/lib/storage/libg_fc/common/cmd.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM /*LINTLIBRARY*/
28*7836SJohn.Forte@Sun.COM 
29*7836SJohn.Forte@Sun.COM /*
30*7836SJohn.Forte@Sun.COM  *  This module is part of the photon Command Line
31*7836SJohn.Forte@Sun.COM  *  Interface program.
32*7836SJohn.Forte@Sun.COM  *
33*7836SJohn.Forte@Sun.COM  */
34*7836SJohn.Forte@Sun.COM 
35*7836SJohn.Forte@Sun.COM /*
36*7836SJohn.Forte@Sun.COM  * I18N message number ranges
37*7836SJohn.Forte@Sun.COM  *  This file: 9500 - 9999
38*7836SJohn.Forte@Sun.COM  *  Shared common messages: 1 - 1999
39*7836SJohn.Forte@Sun.COM  */
40*7836SJohn.Forte@Sun.COM 
41*7836SJohn.Forte@Sun.COM /*	Includes	*/
42*7836SJohn.Forte@Sun.COM #include	<stdlib.h>
43*7836SJohn.Forte@Sun.COM #include	<stdio.h>
44*7836SJohn.Forte@Sun.COM #include	<sys/types.h>
45*7836SJohn.Forte@Sun.COM #include	<unistd.h>
46*7836SJohn.Forte@Sun.COM #include	<errno.h>
47*7836SJohn.Forte@Sun.COM #include	<string.h>
48*7836SJohn.Forte@Sun.COM #include	<sys/scsi/scsi.h>
49*7836SJohn.Forte@Sun.COM #include	<nl_types.h>
50*7836SJohn.Forte@Sun.COM #include	<sys/time.h>
51*7836SJohn.Forte@Sun.COM #include	<l_common.h>
52*7836SJohn.Forte@Sun.COM #include	<stgcom.h>
53*7836SJohn.Forte@Sun.COM #include	<l_error.h>
54*7836SJohn.Forte@Sun.COM #include	<g_state.h>
55*7836SJohn.Forte@Sun.COM 
56*7836SJohn.Forte@Sun.COM 
57*7836SJohn.Forte@Sun.COM /*	Defines		*/
58*7836SJohn.Forte@Sun.COM #define	MAXLEN		1000
59*7836SJohn.Forte@Sun.COM 
60*7836SJohn.Forte@Sun.COM 
61*7836SJohn.Forte@Sun.COM /*	Global variables	*/
62*7836SJohn.Forte@Sun.COM extern	nl_catd l_catd;
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM 
65*7836SJohn.Forte@Sun.COM /*	External functions	*/
66*7836SJohn.Forte@Sun.COM extern	int	rand_r(unsigned int *);
67*7836SJohn.Forte@Sun.COM 
68*7836SJohn.Forte@Sun.COM 
69*7836SJohn.Forte@Sun.COM static int
wait_random_time(void)70*7836SJohn.Forte@Sun.COM wait_random_time(void)
71*7836SJohn.Forte@Sun.COM {
72*7836SJohn.Forte@Sun.COM time_t		timeval;
73*7836SJohn.Forte@Sun.COM struct tm	*tmbuf = NULL;
74*7836SJohn.Forte@Sun.COM struct timeval	tval;
75*7836SJohn.Forte@Sun.COM unsigned int	seed;
76*7836SJohn.Forte@Sun.COM int		random;
77*7836SJohn.Forte@Sun.COM pid_t		pid;
78*7836SJohn.Forte@Sun.COM 
79*7836SJohn.Forte@Sun.COM 
80*7836SJohn.Forte@Sun.COM 	/*
81*7836SJohn.Forte@Sun.COM 	 * Get the system time and use "system seconds"
82*7836SJohn.Forte@Sun.COM 	 * as 'seed' to generate a random number. Then,
83*7836SJohn.Forte@Sun.COM 	 * wait between 1/10 - 1/2 seconds before retry.
84*7836SJohn.Forte@Sun.COM 	 * Get the current process id and ex-or it with
85*7836SJohn.Forte@Sun.COM 	 * the seed so that the random number is always
86*7836SJohn.Forte@Sun.COM 	 * different even in case of multiple processes
87*7836SJohn.Forte@Sun.COM 	 * generate a random number at the same time.
88*7836SJohn.Forte@Sun.COM 	 */
89*7836SJohn.Forte@Sun.COM 	if ((timeval = time(NULL)) == -1) {
90*7836SJohn.Forte@Sun.COM 		return (errno);
91*7836SJohn.Forte@Sun.COM 	}
92*7836SJohn.Forte@Sun.COM 	if ((tmbuf = localtime(&timeval)) == NULL) {
93*7836SJohn.Forte@Sun.COM 		return (L_LOCALTIME_ERROR);
94*7836SJohn.Forte@Sun.COM 	}
95*7836SJohn.Forte@Sun.COM 
96*7836SJohn.Forte@Sun.COM 	pid = getpid();
97*7836SJohn.Forte@Sun.COM 
98*7836SJohn.Forte@Sun.COM 	/* get a random number. */
99*7836SJohn.Forte@Sun.COM 	seed = (unsigned int) tmbuf->tm_sec;
100*7836SJohn.Forte@Sun.COM 	seed ^= pid;
101*7836SJohn.Forte@Sun.COM 	random = rand_r(&seed);
102*7836SJohn.Forte@Sun.COM 
103*7836SJohn.Forte@Sun.COM 
104*7836SJohn.Forte@Sun.COM 	random = ((random % 500) + 100) * MILLISEC;
105*7836SJohn.Forte@Sun.COM 	tval.tv_sec = random / MICROSEC;
106*7836SJohn.Forte@Sun.COM 	tval.tv_usec = random % MICROSEC;
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM 	if (select(0, NULL, NULL, NULL, &tval) == -1) {
109*7836SJohn.Forte@Sun.COM 		return (L_SELECT_ERROR);
110*7836SJohn.Forte@Sun.COM 	}
111*7836SJohn.Forte@Sun.COM 	return (0);
112*7836SJohn.Forte@Sun.COM }
113*7836SJohn.Forte@Sun.COM 
114*7836SJohn.Forte@Sun.COM 
115*7836SJohn.Forte@Sun.COM 
116*7836SJohn.Forte@Sun.COM /*
117*7836SJohn.Forte@Sun.COM  * Execute a command and determine the result.
118*7836SJohn.Forte@Sun.COM  */
119*7836SJohn.Forte@Sun.COM int
cmd(int file,struct uscsi_cmd * command,int flag)120*7836SJohn.Forte@Sun.COM cmd(int file, struct uscsi_cmd *command, int flag)
121*7836SJohn.Forte@Sun.COM {
122*7836SJohn.Forte@Sun.COM struct scsi_extended_sense	*rqbuf;
123*7836SJohn.Forte@Sun.COM int				status, i, retry_cnt = 0, err;
124*7836SJohn.Forte@Sun.COM char				errorMsg[MAXLEN];
125*7836SJohn.Forte@Sun.COM 
126*7836SJohn.Forte@Sun.COM 	/*
127*7836SJohn.Forte@Sun.COM 	 * Set function flags for driver.
128*7836SJohn.Forte@Sun.COM 	 *
129*7836SJohn.Forte@Sun.COM 	 * Set Automatic request sense enable
130*7836SJohn.Forte@Sun.COM 	 *
131*7836SJohn.Forte@Sun.COM 	 */
132*7836SJohn.Forte@Sun.COM 	command->uscsi_flags = USCSI_RQENABLE;
133*7836SJohn.Forte@Sun.COM 	command->uscsi_flags |= flag;
134*7836SJohn.Forte@Sun.COM 
135*7836SJohn.Forte@Sun.COM 	/* intialize error message array */
136*7836SJohn.Forte@Sun.COM 	errorMsg[0] = '\0';
137*7836SJohn.Forte@Sun.COM 
138*7836SJohn.Forte@Sun.COM 	/* print command for debug */
139*7836SJohn.Forte@Sun.COM 	if (getenv("_LUX_S_DEBUG") != NULL) {
140*7836SJohn.Forte@Sun.COM 		if ((command->uscsi_cdb == NULL) ||
141*7836SJohn.Forte@Sun.COM 			(flag & USCSI_RESET) ||
142*7836SJohn.Forte@Sun.COM 			(flag & USCSI_RESET_ALL)) {
143*7836SJohn.Forte@Sun.COM 			if (flag & USCSI_RESET) {
144*7836SJohn.Forte@Sun.COM 				(void) printf("  Issuing a SCSI Reset.\n");
145*7836SJohn.Forte@Sun.COM 			}
146*7836SJohn.Forte@Sun.COM 			if (flag & USCSI_RESET_ALL) {
147*7836SJohn.Forte@Sun.COM 				(void) printf("  Issuing a SCSI Reset All.\n");
148*7836SJohn.Forte@Sun.COM 			}
149*7836SJohn.Forte@Sun.COM 
150*7836SJohn.Forte@Sun.COM 		} else {
151*7836SJohn.Forte@Sun.COM 			(void) printf("  Issuing the following "
152*7836SJohn.Forte@Sun.COM 				"SCSI command: %s\n",
153*7836SJohn.Forte@Sun.COM 			g_scsi_find_command_name(command->uscsi_cdb[0]));
154*7836SJohn.Forte@Sun.COM 			(void) printf("	fd=0x%x cdb=", file);
155*7836SJohn.Forte@Sun.COM 			for (i = 0; i < (int)command->uscsi_cdblen; i++) {
156*7836SJohn.Forte@Sun.COM 				(void) printf("%x ", *(command->uscsi_cdb + i));
157*7836SJohn.Forte@Sun.COM 			}
158*7836SJohn.Forte@Sun.COM 			(void) printf("\n\tlen=0x%x bufaddr=0x%x buflen=0x%x"
159*7836SJohn.Forte@Sun.COM 				" flags=0x%x\n",
160*7836SJohn.Forte@Sun.COM 			command->uscsi_cdblen,
161*7836SJohn.Forte@Sun.COM 			command->uscsi_bufaddr,
162*7836SJohn.Forte@Sun.COM 			command->uscsi_buflen, command->uscsi_flags);
163*7836SJohn.Forte@Sun.COM 
164*7836SJohn.Forte@Sun.COM 			if ((command->uscsi_buflen > 0) &&
165*7836SJohn.Forte@Sun.COM 				((flag & USCSI_READ) == 0)) {
166*7836SJohn.Forte@Sun.COM 				(void) g_dump("  Buffer data: ",
167*7836SJohn.Forte@Sun.COM 				(uchar_t *)command->uscsi_bufaddr,
168*7836SJohn.Forte@Sun.COM 				MIN(command->uscsi_buflen, 512), HEX_ASCII);
169*7836SJohn.Forte@Sun.COM 			}
170*7836SJohn.Forte@Sun.COM 		}
171*7836SJohn.Forte@Sun.COM 		fflush(stdout);
172*7836SJohn.Forte@Sun.COM 	}
173*7836SJohn.Forte@Sun.COM 
174*7836SJohn.Forte@Sun.COM 
175*7836SJohn.Forte@Sun.COM 	/*
176*7836SJohn.Forte@Sun.COM 	 * Default command timeout in case command left it 0
177*7836SJohn.Forte@Sun.COM 	 */
178*7836SJohn.Forte@Sun.COM 	if (command->uscsi_timeout == 0) {
179*7836SJohn.Forte@Sun.COM 		command->uscsi_timeout = 60;
180*7836SJohn.Forte@Sun.COM 	}
181*7836SJohn.Forte@Sun.COM 	/*	Issue command - finally */
182*7836SJohn.Forte@Sun.COM 
183*7836SJohn.Forte@Sun.COM retry:
184*7836SJohn.Forte@Sun.COM 	status = ioctl(file, USCSICMD, command);
185*7836SJohn.Forte@Sun.COM 	if (status == 0 && command->uscsi_status == 0) {
186*7836SJohn.Forte@Sun.COM 		if (getenv("_LUX_S_DEBUG") != NULL) {
187*7836SJohn.Forte@Sun.COM 			if ((command->uscsi_buflen > 0) &&
188*7836SJohn.Forte@Sun.COM 				(flag & USCSI_READ)) {
189*7836SJohn.Forte@Sun.COM 				(void) g_dump("\tData read:",
190*7836SJohn.Forte@Sun.COM 				(uchar_t *)command->uscsi_bufaddr,
191*7836SJohn.Forte@Sun.COM 				MIN(command->uscsi_buflen, 512), HEX_ASCII);
192*7836SJohn.Forte@Sun.COM 			}
193*7836SJohn.Forte@Sun.COM 		}
194*7836SJohn.Forte@Sun.COM 		return (status);
195*7836SJohn.Forte@Sun.COM 	}
196*7836SJohn.Forte@Sun.COM 	if ((status != 0) && (command->uscsi_status == 0)) {
197*7836SJohn.Forte@Sun.COM 		if ((getenv("_LUX_S_DEBUG") != NULL) ||
198*7836SJohn.Forte@Sun.COM 			(getenv("_LUX_ER_DEBUG") != NULL)) {
199*7836SJohn.Forte@Sun.COM 			(void) printf("Unexpected USCSICMD ioctl error: %s\n",
200*7836SJohn.Forte@Sun.COM 				strerror(errno));
201*7836SJohn.Forte@Sun.COM 		}
202*7836SJohn.Forte@Sun.COM 		return (status);
203*7836SJohn.Forte@Sun.COM 	}
204*7836SJohn.Forte@Sun.COM 
205*7836SJohn.Forte@Sun.COM 	/*
206*7836SJohn.Forte@Sun.COM 	 * Just a SCSI error, create error message
207*7836SJohn.Forte@Sun.COM 	 * Retry once for Unit Attention,
208*7836SJohn.Forte@Sun.COM 	 * Not Ready, and Aborted Command
209*7836SJohn.Forte@Sun.COM 	 */
210*7836SJohn.Forte@Sun.COM 	if ((command->uscsi_rqbuf != NULL) &&
211*7836SJohn.Forte@Sun.COM 	    (((char)command->uscsi_rqlen - (char)command->uscsi_rqresid) > 0)) {
212*7836SJohn.Forte@Sun.COM 
213*7836SJohn.Forte@Sun.COM 		rqbuf = (struct scsi_extended_sense *)command->uscsi_rqbuf;
214*7836SJohn.Forte@Sun.COM 
215*7836SJohn.Forte@Sun.COM 		switch (rqbuf->es_key) {
216*7836SJohn.Forte@Sun.COM 		case KEY_NOT_READY:
217*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
218*7836SJohn.Forte@Sun.COM 				ER_DPRINTF("Note: Device Not Ready."
219*7836SJohn.Forte@Sun.COM 						" Retrying...\n");
220*7836SJohn.Forte@Sun.COM 
221*7836SJohn.Forte@Sun.COM 				if ((err = wait_random_time()) == 0) {
222*7836SJohn.Forte@Sun.COM 					goto retry;
223*7836SJohn.Forte@Sun.COM 				} else {
224*7836SJohn.Forte@Sun.COM 					return (err);
225*7836SJohn.Forte@Sun.COM 				}
226*7836SJohn.Forte@Sun.COM 			}
227*7836SJohn.Forte@Sun.COM 			break;
228*7836SJohn.Forte@Sun.COM 
229*7836SJohn.Forte@Sun.COM 		case KEY_UNIT_ATTENTION:
230*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
231*7836SJohn.Forte@Sun.COM 				ER_DPRINTF("  cmd():"
232*7836SJohn.Forte@Sun.COM 				" UNIT_ATTENTION: Retrying...\n");
233*7836SJohn.Forte@Sun.COM 
234*7836SJohn.Forte@Sun.COM 				goto retry;
235*7836SJohn.Forte@Sun.COM 			}
236*7836SJohn.Forte@Sun.COM 			break;
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM 		case KEY_ABORTED_COMMAND:
239*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
240*7836SJohn.Forte@Sun.COM 				ER_DPRINTF("Note: Command is aborted."
241*7836SJohn.Forte@Sun.COM 				" Retrying...\n");
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 				goto retry;
244*7836SJohn.Forte@Sun.COM 			}
245*7836SJohn.Forte@Sun.COM 			break;
246*7836SJohn.Forte@Sun.COM 		}
247*7836SJohn.Forte@Sun.COM 		if ((getenv("_LUX_S_DEBUG") != NULL) ||
248*7836SJohn.Forte@Sun.COM 			(getenv("_LUX_ER_DEBUG") != NULL)) {
249*7836SJohn.Forte@Sun.COM 			g_scsi_printerr(command,
250*7836SJohn.Forte@Sun.COM 			(struct scsi_extended_sense *)command->uscsi_rqbuf,
251*7836SJohn.Forte@Sun.COM 			(command->uscsi_rqlen - command->uscsi_rqresid),
252*7836SJohn.Forte@Sun.COM 				errorMsg, strerror(errno));
253*7836SJohn.Forte@Sun.COM 		}
254*7836SJohn.Forte@Sun.COM 
255*7836SJohn.Forte@Sun.COM 	} else {
256*7836SJohn.Forte@Sun.COM 
257*7836SJohn.Forte@Sun.COM 		/*
258*7836SJohn.Forte@Sun.COM 		 * Retry 5 times in case of BUSY, and only
259*7836SJohn.Forte@Sun.COM 		 * once for Reservation-conflict, Command
260*7836SJohn.Forte@Sun.COM 		 * Termination and Queue Full. Wait for
261*7836SJohn.Forte@Sun.COM 		 * random amount of time (between 1/10 - 1/2 secs.)
262*7836SJohn.Forte@Sun.COM 		 * between each retry. This random wait is to avoid
263*7836SJohn.Forte@Sun.COM 		 * the multiple threads being executed at the same time
264*7836SJohn.Forte@Sun.COM 		 * and also the constraint in Photon IB, where the
265*7836SJohn.Forte@Sun.COM 		 * command queue has a depth of one command.
266*7836SJohn.Forte@Sun.COM 		 */
267*7836SJohn.Forte@Sun.COM 		switch ((uchar_t)command->uscsi_status & STATUS_MASK) {
268*7836SJohn.Forte@Sun.COM 		case STATUS_BUSY:
269*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 5) {
270*7836SJohn.Forte@Sun.COM 				if ((err = wait_random_time()) == 0) {
271*7836SJohn.Forte@Sun.COM 					R_DPRINTF("  cmd(): No. of retries %d."
272*7836SJohn.Forte@Sun.COM 					" STATUS_BUSY: Retrying...\n",
273*7836SJohn.Forte@Sun.COM 					retry_cnt);
274*7836SJohn.Forte@Sun.COM 					goto retry;
275*7836SJohn.Forte@Sun.COM 
276*7836SJohn.Forte@Sun.COM 				} else {
277*7836SJohn.Forte@Sun.COM 					return (err);
278*7836SJohn.Forte@Sun.COM 				}
279*7836SJohn.Forte@Sun.COM 			}
280*7836SJohn.Forte@Sun.COM 			break;
281*7836SJohn.Forte@Sun.COM 
282*7836SJohn.Forte@Sun.COM 		case STATUS_RESERVATION_CONFLICT:
283*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
284*7836SJohn.Forte@Sun.COM 				if ((err = wait_random_time()) == 0) {
285*7836SJohn.Forte@Sun.COM 					R_DPRINTF("  cmd():"
286*7836SJohn.Forte@Sun.COM 					" RESERVATION_CONFLICT:"
287*7836SJohn.Forte@Sun.COM 					" Retrying...\n");
288*7836SJohn.Forte@Sun.COM 					goto retry;
289*7836SJohn.Forte@Sun.COM 
290*7836SJohn.Forte@Sun.COM 				} else {
291*7836SJohn.Forte@Sun.COM 					return (err);
292*7836SJohn.Forte@Sun.COM 				}
293*7836SJohn.Forte@Sun.COM 			}
294*7836SJohn.Forte@Sun.COM 			break;
295*7836SJohn.Forte@Sun.COM 
296*7836SJohn.Forte@Sun.COM 		case STATUS_TERMINATED:
297*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
298*7836SJohn.Forte@Sun.COM 				R_DPRINTF("Note: Command Terminated."
299*7836SJohn.Forte@Sun.COM 					" Retrying...\n");
300*7836SJohn.Forte@Sun.COM 
301*7836SJohn.Forte@Sun.COM 				if ((err = wait_random_time()) == 0) {
302*7836SJohn.Forte@Sun.COM 					goto retry;
303*7836SJohn.Forte@Sun.COM 				} else {
304*7836SJohn.Forte@Sun.COM 					return (err);
305*7836SJohn.Forte@Sun.COM 				}
306*7836SJohn.Forte@Sun.COM 			}
307*7836SJohn.Forte@Sun.COM 			break;
308*7836SJohn.Forte@Sun.COM 
309*7836SJohn.Forte@Sun.COM 		case STATUS_QFULL:
310*7836SJohn.Forte@Sun.COM 			if (retry_cnt++ < 1) {
311*7836SJohn.Forte@Sun.COM 				R_DPRINTF("Note: Command Queue is full."
312*7836SJohn.Forte@Sun.COM 				" Retrying...\n");
313*7836SJohn.Forte@Sun.COM 
314*7836SJohn.Forte@Sun.COM 				if ((err = wait_random_time()) == 0) {
315*7836SJohn.Forte@Sun.COM 					goto retry;
316*7836SJohn.Forte@Sun.COM 				} else {
317*7836SJohn.Forte@Sun.COM 					return (err);
318*7836SJohn.Forte@Sun.COM 				}
319*7836SJohn.Forte@Sun.COM 			}
320*7836SJohn.Forte@Sun.COM 			break;
321*7836SJohn.Forte@Sun.COM 		}
322*7836SJohn.Forte@Sun.COM 
323*7836SJohn.Forte@Sun.COM 	}
324*7836SJohn.Forte@Sun.COM 	if (((getenv("_LUX_S_DEBUG") != NULL) ||
325*7836SJohn.Forte@Sun.COM 		(getenv("_LUX_ER_DEBUG") != NULL)) &&
326*7836SJohn.Forte@Sun.COM 		(errorMsg[0] != '\0')) {
327*7836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "  %s\n", errorMsg);
328*7836SJohn.Forte@Sun.COM 	}
329*7836SJohn.Forte@Sun.COM 	return (L_SCSI_ERROR | command->uscsi_status);
330*7836SJohn.Forte@Sun.COM }
331