xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_scsi.c (revision 7917:5c4442486198)
1*7917SReza.Sabdar@Sun.COM /*
2*7917SReza.Sabdar@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*7917SReza.Sabdar@Sun.COM  * Use is subject to license terms.
4*7917SReza.Sabdar@Sun.COM  */
5*7917SReza.Sabdar@Sun.COM 
6*7917SReza.Sabdar@Sun.COM /*
7*7917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
8*7917SReza.Sabdar@Sun.COM  *
9*7917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
10*7917SReza.Sabdar@Sun.COM  *
11*7917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
12*7917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
13*7917SReza.Sabdar@Sun.COM  * are met:
14*7917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
15*7917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
16*7917SReza.Sabdar@Sun.COM  *
17*7917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
18*7917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
19*7917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
20*7917SReza.Sabdar@Sun.COM  *	  distribution.
21*7917SReza.Sabdar@Sun.COM  *
22*7917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23*7917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
24*7917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
25*7917SReza.Sabdar@Sun.COM  *	  permission.
26*7917SReza.Sabdar@Sun.COM  *
27*7917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*7917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*7917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*7917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*7917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*7917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*7917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*7917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*7917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*7917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*7917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
38*7917SReza.Sabdar@Sun.COM  */
39*7917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
40*7917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
41*7917SReza.Sabdar@Sun.COM 
42*7917SReza.Sabdar@Sun.COM #include <sys/types.h>
43*7917SReza.Sabdar@Sun.COM #include <ctype.h>
44*7917SReza.Sabdar@Sun.COM #include <errno.h>
45*7917SReza.Sabdar@Sun.COM #include <fcntl.h>
46*7917SReza.Sabdar@Sun.COM #include <stdlib.h>
47*7917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
48*7917SReza.Sabdar@Sun.COM #include "ndmpd.h"
49*7917SReza.Sabdar@Sun.COM #include <string.h>
50*7917SReza.Sabdar@Sun.COM #include <sys/scsi/impl/uscsi.h>
51*7917SReza.Sabdar@Sun.COM #include <sys/scsi/scsi.h>
52*7917SReza.Sabdar@Sun.COM 
53*7917SReza.Sabdar@Sun.COM static void scsi_open_send_reply(ndmp_connection_t *connection, int err);
54*7917SReza.Sabdar@Sun.COM static void common_open(ndmp_connection_t *connection, char *devname);
55*7917SReza.Sabdar@Sun.COM static void common_set_target(ndmp_connection_t *connection, char *device,
56*7917SReza.Sabdar@Sun.COM     ushort_t controller, ushort_t sid, ushort_t lun);
57*7917SReza.Sabdar@Sun.COM 
58*7917SReza.Sabdar@Sun.COM 
59*7917SReza.Sabdar@Sun.COM /*
60*7917SReza.Sabdar@Sun.COM  * ************************************************************************
61*7917SReza.Sabdar@Sun.COM  * NDMP V2 HANDLERS
62*7917SReza.Sabdar@Sun.COM  * ************************************************************************
63*7917SReza.Sabdar@Sun.COM  */
64*7917SReza.Sabdar@Sun.COM 
65*7917SReza.Sabdar@Sun.COM /*
66*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_open_v2
67*7917SReza.Sabdar@Sun.COM  *
68*7917SReza.Sabdar@Sun.COM  * This handler opens the specified SCSI device.
69*7917SReza.Sabdar@Sun.COM  *
70*7917SReza.Sabdar@Sun.COM  * Parameters:
71*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
72*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
73*7917SReza.Sabdar@Sun.COM  *
74*7917SReza.Sabdar@Sun.COM  * Returns:
75*7917SReza.Sabdar@Sun.COM  *   void
76*7917SReza.Sabdar@Sun.COM  */
77*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_open_v2(ndmp_connection_t * connection,void * body)78*7917SReza.Sabdar@Sun.COM ndmpd_scsi_open_v2(ndmp_connection_t *connection, void *body)
79*7917SReza.Sabdar@Sun.COM {
80*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_open_request_v2 *request = (ndmp_scsi_open_request_v2 *)body;
81*7917SReza.Sabdar@Sun.COM 
82*7917SReza.Sabdar@Sun.COM 	common_open(connection, request->device.name);
83*7917SReza.Sabdar@Sun.COM }
84*7917SReza.Sabdar@Sun.COM 
85*7917SReza.Sabdar@Sun.COM 
86*7917SReza.Sabdar@Sun.COM /*
87*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_close_v2
88*7917SReza.Sabdar@Sun.COM  *
89*7917SReza.Sabdar@Sun.COM  * This handler closes the currently open SCSI device.
90*7917SReza.Sabdar@Sun.COM  *
91*7917SReza.Sabdar@Sun.COM  * Parameters:
92*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
93*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
94*7917SReza.Sabdar@Sun.COM  *
95*7917SReza.Sabdar@Sun.COM  * Returns:
96*7917SReza.Sabdar@Sun.COM  *   void
97*7917SReza.Sabdar@Sun.COM  */
98*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/
99*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_close_v2(ndmp_connection_t * connection,void * body)100*7917SReza.Sabdar@Sun.COM ndmpd_scsi_close_v2(ndmp_connection_t *connection, void *body)
101*7917SReza.Sabdar@Sun.COM {
102*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_close_reply reply;
103*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
104*7917SReza.Sabdar@Sun.COM 
105*7917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_is_open == -1) {
106*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "SCSI device is not open.");
107*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_DEV_NOT_OPEN_ERR;
108*7917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, (void *) &reply,
109*7917SReza.Sabdar@Sun.COM 		    "sending scsi_close reply");
110*7917SReza.Sabdar@Sun.COM 		return;
111*7917SReza.Sabdar@Sun.COM 	}
112*7917SReza.Sabdar@Sun.COM 	(void) ndmp_open_list_del(session->ns_scsi.sd_adapter_name,
113*7917SReza.Sabdar@Sun.COM 	    session->ns_scsi.sd_sid,
114*7917SReza.Sabdar@Sun.COM 	    session->ns_scsi.sd_lun);
115*7917SReza.Sabdar@Sun.COM 	(void) close(session->ns_scsi.sd_devid);
116*7917SReza.Sabdar@Sun.COM 
117*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_is_open = -1;
118*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_devid = -1;
119*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_sid = 0;
120*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_lun = 0;
121*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_valid_target_set = FALSE;
122*7917SReza.Sabdar@Sun.COM 	(void) memset(session->ns_scsi.sd_adapter_name, 0,
123*7917SReza.Sabdar@Sun.COM 	    sizeof (session->ns_scsi.sd_adapter_name));
124*7917SReza.Sabdar@Sun.COM 
125*7917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
126*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
127*7917SReza.Sabdar@Sun.COM 	    "sending scsi_close reply");
128*7917SReza.Sabdar@Sun.COM }
129*7917SReza.Sabdar@Sun.COM 
130*7917SReza.Sabdar@Sun.COM 
131*7917SReza.Sabdar@Sun.COM /*
132*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_get_state_v2
133*7917SReza.Sabdar@Sun.COM  *
134*7917SReza.Sabdar@Sun.COM  * This handler returns state information for the currently open SCSI device.
135*7917SReza.Sabdar@Sun.COM  * Since the implementation only supports the opening of a specific SCSI
136*7917SReza.Sabdar@Sun.COM  * device, as opposed to a device that can talk to multiple SCSI targets,
137*7917SReza.Sabdar@Sun.COM  * this request is not supported. This request is only appropriate for
138*7917SReza.Sabdar@Sun.COM  * implementations that support device files that can target multiple
139*7917SReza.Sabdar@Sun.COM  * SCSI devices.
140*7917SReza.Sabdar@Sun.COM  *
141*7917SReza.Sabdar@Sun.COM  * Parameters:
142*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
143*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
144*7917SReza.Sabdar@Sun.COM  *
145*7917SReza.Sabdar@Sun.COM  * Returns:
146*7917SReza.Sabdar@Sun.COM  *   void
147*7917SReza.Sabdar@Sun.COM  */
148*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/
149*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_get_state_v2(ndmp_connection_t * connection,void * body)150*7917SReza.Sabdar@Sun.COM ndmpd_scsi_get_state_v2(ndmp_connection_t *connection, void *body)
151*7917SReza.Sabdar@Sun.COM {
152*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_get_state_reply reply;
153*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
154*7917SReza.Sabdar@Sun.COM 
155*7917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_is_open == -1)
156*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_DEV_NOT_OPEN_ERR;
157*7917SReza.Sabdar@Sun.COM 	else if (!session->ns_scsi.sd_valid_target_set) {
158*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
159*7917SReza.Sabdar@Sun.COM 		reply.target_controller = -1;
160*7917SReza.Sabdar@Sun.COM 		reply.target_id = -1;
161*7917SReza.Sabdar@Sun.COM 		reply.target_lun = -1;
162*7917SReza.Sabdar@Sun.COM 	} else {
163*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
164*7917SReza.Sabdar@Sun.COM 		reply.target_controller = 0;
165*7917SReza.Sabdar@Sun.COM 		reply.target_id = session->ns_scsi.sd_sid;
166*7917SReza.Sabdar@Sun.COM 		reply.target_lun = session->ns_scsi.sd_lun;
167*7917SReza.Sabdar@Sun.COM 	}
168*7917SReza.Sabdar@Sun.COM 
169*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
170*7917SReza.Sabdar@Sun.COM 	    "sending scsi_get_state reply");
171*7917SReza.Sabdar@Sun.COM }
172*7917SReza.Sabdar@Sun.COM 
173*7917SReza.Sabdar@Sun.COM 
174*7917SReza.Sabdar@Sun.COM /*
175*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_set_target_v2
176*7917SReza.Sabdar@Sun.COM  *
177*7917SReza.Sabdar@Sun.COM  * This handler sets the SCSI target of the SCSI device.
178*7917SReza.Sabdar@Sun.COM  * It is only valid to use this request if the opened SCSI device
179*7917SReza.Sabdar@Sun.COM  * is capable of talking to multiple SCSI targets.
180*7917SReza.Sabdar@Sun.COM  * Since the implementation only supports the opening of a specific SCSI
181*7917SReza.Sabdar@Sun.COM  * device, as opposed to a device that can talk to multiple SCSI targets,
182*7917SReza.Sabdar@Sun.COM  * this request is not supported. This request is only appropriate for
183*7917SReza.Sabdar@Sun.COM  * implementations that support device files that can target multiple
184*7917SReza.Sabdar@Sun.COM  * SCSI devices.
185*7917SReza.Sabdar@Sun.COM  *
186*7917SReza.Sabdar@Sun.COM  * Parameters:
187*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
188*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
189*7917SReza.Sabdar@Sun.COM  *
190*7917SReza.Sabdar@Sun.COM  * Returns:
191*7917SReza.Sabdar@Sun.COM  *   void
192*7917SReza.Sabdar@Sun.COM  */
193*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_set_target_v2(ndmp_connection_t * connection,void * body)194*7917SReza.Sabdar@Sun.COM ndmpd_scsi_set_target_v2(ndmp_connection_t *connection, void *body)
195*7917SReza.Sabdar@Sun.COM {
196*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_set_target_request_v2 *request;
197*7917SReza.Sabdar@Sun.COM 
198*7917SReza.Sabdar@Sun.COM 	request = (ndmp_scsi_set_target_request_v2 *) body;
199*7917SReza.Sabdar@Sun.COM 
200*7917SReza.Sabdar@Sun.COM 	common_set_target(connection, request->device.name,
201*7917SReza.Sabdar@Sun.COM 	    request->target_controller, request->target_id,
202*7917SReza.Sabdar@Sun.COM 	    request->target_lun);
203*7917SReza.Sabdar@Sun.COM }
204*7917SReza.Sabdar@Sun.COM 
205*7917SReza.Sabdar@Sun.COM 
206*7917SReza.Sabdar@Sun.COM /*
207*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_reset_device_v2
208*7917SReza.Sabdar@Sun.COM  *
209*7917SReza.Sabdar@Sun.COM  * This handler resets the currently targeted SCSI device.
210*7917SReza.Sabdar@Sun.COM  *
211*7917SReza.Sabdar@Sun.COM  * Parameters:
212*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
213*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
214*7917SReza.Sabdar@Sun.COM  *
215*7917SReza.Sabdar@Sun.COM  * Returns:
216*7917SReza.Sabdar@Sun.COM  *   void
217*7917SReza.Sabdar@Sun.COM  */
218*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/
219*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_reset_device_v2(ndmp_connection_t * connection,void * body)220*7917SReza.Sabdar@Sun.COM ndmpd_scsi_reset_device_v2(ndmp_connection_t *connection, void *body)
221*7917SReza.Sabdar@Sun.COM {
222*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_reset_device_reply reply;
223*7917SReza.Sabdar@Sun.COM 
224*7917SReza.Sabdar@Sun.COM 
225*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
226*7917SReza.Sabdar@Sun.COM 	struct uscsi_cmd  cmd;
227*7917SReza.Sabdar@Sun.COM 
228*7917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_devid == -1) {
229*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "SCSI device is not open.");
230*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_DEV_NOT_OPEN_ERR;
231*7917SReza.Sabdar@Sun.COM 	} else {
232*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_ERR;
233*7917SReza.Sabdar@Sun.COM 		(void) memset((void*)&cmd, 0, sizeof (cmd));
234*7917SReza.Sabdar@Sun.COM 		cmd.uscsi_flags |= USCSI_RESET;
235*7917SReza.Sabdar@Sun.COM 		if (ioctl(session->ns_scsi.sd_devid, USCSICMD, &cmd) < 0) {
236*7917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "USCSI reset failed: %m.");
237*7917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
238*7917SReza.Sabdar@Sun.COM 			    "ioctl(USCSICMD) USCSI_RESET failed: %m.");
239*7917SReza.Sabdar@Sun.COM 			reply.error = NDMP_IO_ERR;
240*7917SReza.Sabdar@Sun.COM 		}
241*7917SReza.Sabdar@Sun.COM 	}
242*7917SReza.Sabdar@Sun.COM 
243*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
244*7917SReza.Sabdar@Sun.COM 	    "sending scsi_reset_device reply");
245*7917SReza.Sabdar@Sun.COM }
246*7917SReza.Sabdar@Sun.COM 
247*7917SReza.Sabdar@Sun.COM 
248*7917SReza.Sabdar@Sun.COM /*
249*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_reset_bus_v2
250*7917SReza.Sabdar@Sun.COM  *
251*7917SReza.Sabdar@Sun.COM  * This handler resets the currently targeted SCSI bus.
252*7917SReza.Sabdar@Sun.COM  *
253*7917SReza.Sabdar@Sun.COM  * Request not yet supported.
254*7917SReza.Sabdar@Sun.COM  *
255*7917SReza.Sabdar@Sun.COM  * Parameters:
256*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
257*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
258*7917SReza.Sabdar@Sun.COM  *
259*7917SReza.Sabdar@Sun.COM  * Returns:
260*7917SReza.Sabdar@Sun.COM  *   void
261*7917SReza.Sabdar@Sun.COM  */
262*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/
263*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_reset_bus_v2(ndmp_connection_t * connection,void * body)264*7917SReza.Sabdar@Sun.COM ndmpd_scsi_reset_bus_v2(ndmp_connection_t *connection, void *body)
265*7917SReza.Sabdar@Sun.COM {
266*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_reset_bus_reply reply;
267*7917SReza.Sabdar@Sun.COM 
268*7917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "request not supported");
269*7917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NOT_SUPPORTED_ERR;
270*7917SReza.Sabdar@Sun.COM 
271*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
272*7917SReza.Sabdar@Sun.COM 	    "sending scsi_reset_bus reply");
273*7917SReza.Sabdar@Sun.COM }
274*7917SReza.Sabdar@Sun.COM 
275*7917SReza.Sabdar@Sun.COM 
276*7917SReza.Sabdar@Sun.COM /*
277*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_execute_cdb_v2
278*7917SReza.Sabdar@Sun.COM  *
279*7917SReza.Sabdar@Sun.COM  * This handler sends the CDB to the currently targeted SCSI device.
280*7917SReza.Sabdar@Sun.COM  *
281*7917SReza.Sabdar@Sun.COM  * Parameters:
282*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
283*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
284*7917SReza.Sabdar@Sun.COM  *
285*7917SReza.Sabdar@Sun.COM  * Returns:
286*7917SReza.Sabdar@Sun.COM  *   void
287*7917SReza.Sabdar@Sun.COM  */
288*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_execute_cdb_v2(ndmp_connection_t * connection,void * body)289*7917SReza.Sabdar@Sun.COM ndmpd_scsi_execute_cdb_v2(ndmp_connection_t *connection, void *body)
290*7917SReza.Sabdar@Sun.COM {
291*7917SReza.Sabdar@Sun.COM 	ndmp_execute_cdb_request *request = (ndmp_execute_cdb_request *) body;
292*7917SReza.Sabdar@Sun.COM 	ndmp_execute_cdb_reply reply;
293*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
294*7917SReza.Sabdar@Sun.COM 
295*7917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_is_open == -1 ||
296*7917SReza.Sabdar@Sun.COM 	    !session->ns_scsi.sd_valid_target_set) {
297*7917SReza.Sabdar@Sun.COM 		(void) memset((void *) &reply, 0, sizeof (reply));
298*7917SReza.Sabdar@Sun.COM 
299*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "SCSI device is not open.");
300*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_DEV_NOT_OPEN_ERR;
301*7917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, (void *) &reply,
302*7917SReza.Sabdar@Sun.COM 		    "sending scsi_execute_cdb reply");
303*7917SReza.Sabdar@Sun.COM 	} else {
304*7917SReza.Sabdar@Sun.COM 		ndmp_execute_cdb(session, session->ns_scsi.sd_adapter_name,
305*7917SReza.Sabdar@Sun.COM 		    session->ns_scsi.sd_sid, session->ns_scsi.sd_lun, request);
306*7917SReza.Sabdar@Sun.COM 	}
307*7917SReza.Sabdar@Sun.COM }
308*7917SReza.Sabdar@Sun.COM 
309*7917SReza.Sabdar@Sun.COM 
310*7917SReza.Sabdar@Sun.COM /*
311*7917SReza.Sabdar@Sun.COM  * ************************************************************************
312*7917SReza.Sabdar@Sun.COM  * NDMP V3 HANDLERS
313*7917SReza.Sabdar@Sun.COM  * ************************************************************************
314*7917SReza.Sabdar@Sun.COM  */
315*7917SReza.Sabdar@Sun.COM 
316*7917SReza.Sabdar@Sun.COM /*
317*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_open_v3
318*7917SReza.Sabdar@Sun.COM  *
319*7917SReza.Sabdar@Sun.COM  * This handler opens the specified SCSI device.
320*7917SReza.Sabdar@Sun.COM  *
321*7917SReza.Sabdar@Sun.COM  * Parameters:
322*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
323*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
324*7917SReza.Sabdar@Sun.COM  *
325*7917SReza.Sabdar@Sun.COM  * Returns:
326*7917SReza.Sabdar@Sun.COM  *   void
327*7917SReza.Sabdar@Sun.COM  */
328*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_open_v3(ndmp_connection_t * connection,void * body)329*7917SReza.Sabdar@Sun.COM ndmpd_scsi_open_v3(ndmp_connection_t *connection, void *body)
330*7917SReza.Sabdar@Sun.COM {
331*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_open_request_v3 *request = (ndmp_scsi_open_request_v3 *)body;
332*7917SReza.Sabdar@Sun.COM 
333*7917SReza.Sabdar@Sun.COM 	common_open(connection, request->device);
334*7917SReza.Sabdar@Sun.COM }
335*7917SReza.Sabdar@Sun.COM 
336*7917SReza.Sabdar@Sun.COM 
337*7917SReza.Sabdar@Sun.COM /*
338*7917SReza.Sabdar@Sun.COM  * ndmpd_scsi_set_target_v3
339*7917SReza.Sabdar@Sun.COM  *
340*7917SReza.Sabdar@Sun.COM  * This handler sets the SCSI target of the SCSI device.
341*7917SReza.Sabdar@Sun.COM  * It is only valid to use this request if the opened SCSI device
342*7917SReza.Sabdar@Sun.COM  * is capable of talking to multiple SCSI targets.
343*7917SReza.Sabdar@Sun.COM  *
344*7917SReza.Sabdar@Sun.COM  * Parameters:
345*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
346*7917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
347*7917SReza.Sabdar@Sun.COM  *
348*7917SReza.Sabdar@Sun.COM  * Returns:
349*7917SReza.Sabdar@Sun.COM  *   void
350*7917SReza.Sabdar@Sun.COM  */
351*7917SReza.Sabdar@Sun.COM void
ndmpd_scsi_set_target_v3(ndmp_connection_t * connection,void * body)352*7917SReza.Sabdar@Sun.COM ndmpd_scsi_set_target_v3(ndmp_connection_t *connection, void *body)
353*7917SReza.Sabdar@Sun.COM {
354*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_set_target_request_v3 *request;
355*7917SReza.Sabdar@Sun.COM 
356*7917SReza.Sabdar@Sun.COM 	request = (ndmp_scsi_set_target_request_v3 *) body;
357*7917SReza.Sabdar@Sun.COM 
358*7917SReza.Sabdar@Sun.COM 	common_set_target(connection, request->device,
359*7917SReza.Sabdar@Sun.COM 	    request->target_controller, request->target_id,
360*7917SReza.Sabdar@Sun.COM 	    request->target_lun);
361*7917SReza.Sabdar@Sun.COM }
362*7917SReza.Sabdar@Sun.COM 
363*7917SReza.Sabdar@Sun.COM 
364*7917SReza.Sabdar@Sun.COM /*
365*7917SReza.Sabdar@Sun.COM  * ************************************************************************
366*7917SReza.Sabdar@Sun.COM  * NDMP V4 HANDLERS
367*7917SReza.Sabdar@Sun.COM  * ************************************************************************
368*7917SReza.Sabdar@Sun.COM  */
369*7917SReza.Sabdar@Sun.COM 
370*7917SReza.Sabdar@Sun.COM /*
371*7917SReza.Sabdar@Sun.COM  * ************************************************************************
372*7917SReza.Sabdar@Sun.COM  * LOCALS
373*7917SReza.Sabdar@Sun.COM  * ************************************************************************
374*7917SReza.Sabdar@Sun.COM  */
375*7917SReza.Sabdar@Sun.COM 
376*7917SReza.Sabdar@Sun.COM 
377*7917SReza.Sabdar@Sun.COM /*
378*7917SReza.Sabdar@Sun.COM  * scsi_open_send_reply
379*7917SReza.Sabdar@Sun.COM  *
380*7917SReza.Sabdar@Sun.COM  * Send a reply for SCSI open command
381*7917SReza.Sabdar@Sun.COM  *
382*7917SReza.Sabdar@Sun.COM  * Parameters:
383*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
384*7917SReza.Sabdar@Sun.COM  *   err        (input) - ndmp error code
385*7917SReza.Sabdar@Sun.COM  *
386*7917SReza.Sabdar@Sun.COM  * Returns:
387*7917SReza.Sabdar@Sun.COM  *   void
388*7917SReza.Sabdar@Sun.COM  */
389*7917SReza.Sabdar@Sun.COM static void
scsi_open_send_reply(ndmp_connection_t * connection,int err)390*7917SReza.Sabdar@Sun.COM scsi_open_send_reply(ndmp_connection_t *connection, int err)
391*7917SReza.Sabdar@Sun.COM {
392*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_open_reply reply;
393*7917SReza.Sabdar@Sun.COM 
394*7917SReza.Sabdar@Sun.COM 	reply.error = err;
395*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply, "sending scsi_open reply");
396*7917SReza.Sabdar@Sun.COM }
397*7917SReza.Sabdar@Sun.COM 
398*7917SReza.Sabdar@Sun.COM 
399*7917SReza.Sabdar@Sun.COM /*
400*7917SReza.Sabdar@Sun.COM  * common_open
401*7917SReza.Sabdar@Sun.COM  *
402*7917SReza.Sabdar@Sun.COM  * Common SCSI open function for all NDMP versions
403*7917SReza.Sabdar@Sun.COM  *
404*7917SReza.Sabdar@Sun.COM  * Parameters:
405*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
406*7917SReza.Sabdar@Sun.COM  *   devname (input) - device name to open.
407*7917SReza.Sabdar@Sun.COM  *
408*7917SReza.Sabdar@Sun.COM  * Returns:
409*7917SReza.Sabdar@Sun.COM  *   void
410*7917SReza.Sabdar@Sun.COM  */
411*7917SReza.Sabdar@Sun.COM static void
common_open(ndmp_connection_t * connection,char * devname)412*7917SReza.Sabdar@Sun.COM common_open(ndmp_connection_t *connection, char *devname)
413*7917SReza.Sabdar@Sun.COM {
414*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
415*7917SReza.Sabdar@Sun.COM 	char adptnm[SCSI_MAX_NAME];
416*7917SReza.Sabdar@Sun.COM 	int sid, lun;
417*7917SReza.Sabdar@Sun.COM 	int err;
418*7917SReza.Sabdar@Sun.COM 	scsi_adapter_t *sa;
419*7917SReza.Sabdar@Sun.COM 	int devid;
420*7917SReza.Sabdar@Sun.COM 
421*7917SReza.Sabdar@Sun.COM 	err = NDMP_NO_ERR;
422*7917SReza.Sabdar@Sun.COM 
423*7917SReza.Sabdar@Sun.COM 	if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
424*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
425*7917SReza.Sabdar@Sun.COM 		    "Session already has a tape or scsi device open.");
426*7917SReza.Sabdar@Sun.COM 		err = NDMP_DEVICE_OPENED_ERR;
427*7917SReza.Sabdar@Sun.COM 	} else if ((sa = scsi_get_adapter(0)) != NULL) {
428*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Adapter device found: %s", devname);
429*7917SReza.Sabdar@Sun.COM 		(void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
430*7917SReza.Sabdar@Sun.COM 		adptnm[SCSI_MAX_NAME-1] = '\0';
431*7917SReza.Sabdar@Sun.COM 		sid = lun = -1;
432*7917SReza.Sabdar@Sun.COM 
433*7917SReza.Sabdar@Sun.COM 		scsi_find_sid_lun(sa, devname, &sid, &lun);
434*7917SReza.Sabdar@Sun.COM 		if (ndmp_open_list_find(devname, sid, lun) == NULL &&
435*7917SReza.Sabdar@Sun.COM 		    (devid = open(devname, O_RDWR | O_NDELAY)) < 0) {
436*7917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Failed to open device %s: %m.",
437*7917SReza.Sabdar@Sun.COM 			    devname);
438*7917SReza.Sabdar@Sun.COM 			err = NDMP_NO_DEVICE_ERR;
439*7917SReza.Sabdar@Sun.COM 		}
440*7917SReza.Sabdar@Sun.COM 	} else {
441*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "%s: No such SCSI adapter.", devname);
442*7917SReza.Sabdar@Sun.COM 		err = NDMP_NO_DEVICE_ERR;
443*7917SReza.Sabdar@Sun.COM 	}
444*7917SReza.Sabdar@Sun.COM 
445*7917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
446*7917SReza.Sabdar@Sun.COM 		scsi_open_send_reply(connection, err);
447*7917SReza.Sabdar@Sun.COM 		return;
448*7917SReza.Sabdar@Sun.COM 	}
449*7917SReza.Sabdar@Sun.COM 
450*7917SReza.Sabdar@Sun.COM 	switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
451*7917SReza.Sabdar@Sun.COM 	case 0:
452*7917SReza.Sabdar@Sun.COM 		/* OK */
453*7917SReza.Sabdar@Sun.COM 		break;
454*7917SReza.Sabdar@Sun.COM 	case EBUSY:
455*7917SReza.Sabdar@Sun.COM 		err = NDMP_DEVICE_BUSY_ERR;
456*7917SReza.Sabdar@Sun.COM 		break;
457*7917SReza.Sabdar@Sun.COM 	case ENOMEM:
458*7917SReza.Sabdar@Sun.COM 		err = NDMP_NO_MEM_ERR;
459*7917SReza.Sabdar@Sun.COM 		break;
460*7917SReza.Sabdar@Sun.COM 	default:
461*7917SReza.Sabdar@Sun.COM 		err = NDMP_IO_ERR;
462*7917SReza.Sabdar@Sun.COM 	}
463*7917SReza.Sabdar@Sun.COM 	if (err != NDMP_NO_ERR) {
464*7917SReza.Sabdar@Sun.COM 		scsi_open_send_reply(connection, err);
465*7917SReza.Sabdar@Sun.COM 		return;
466*7917SReza.Sabdar@Sun.COM 	}
467*7917SReza.Sabdar@Sun.COM 
468*7917SReza.Sabdar@Sun.COM 	(void) strlcpy(session->ns_scsi.sd_adapter_name, adptnm, SCSI_MAX_NAME);
469*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_is_open = 1;
470*7917SReza.Sabdar@Sun.COM 	session->ns_scsi.sd_devid = devid;
471*7917SReza.Sabdar@Sun.COM 	if (sid != -1) {
472*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_sid = sid;
473*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_lun = lun;
474*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_valid_target_set = TRUE;
475*7917SReza.Sabdar@Sun.COM 	} else {
476*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_sid = session->ns_scsi.sd_lun = -1;
477*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_valid_target_set = FALSE;
478*7917SReza.Sabdar@Sun.COM 	}
479*7917SReza.Sabdar@Sun.COM 
480*7917SReza.Sabdar@Sun.COM 	scsi_open_send_reply(connection, err);
481*7917SReza.Sabdar@Sun.COM }
482*7917SReza.Sabdar@Sun.COM 
483*7917SReza.Sabdar@Sun.COM 
484*7917SReza.Sabdar@Sun.COM /*
485*7917SReza.Sabdar@Sun.COM  * common_set_target
486*7917SReza.Sabdar@Sun.COM  *
487*7917SReza.Sabdar@Sun.COM  * Set the SCSI target (SCSI number, LUN number, controller number)
488*7917SReza.Sabdar@Sun.COM  *
489*7917SReza.Sabdar@Sun.COM  * Parameters:
490*7917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
491*7917SReza.Sabdar@Sun.COM  *   device (input) - device name.
492*7917SReza.Sabdar@Sun.COM  *   controller (input) - controller number.
493*7917SReza.Sabdar@Sun.COM  *   sid (input) - SCSI target ID.
494*7917SReza.Sabdar@Sun.COM  *   lun (input) - LUN number.
495*7917SReza.Sabdar@Sun.COM  *
496*7917SReza.Sabdar@Sun.COM  * Returns:
497*7917SReza.Sabdar@Sun.COM  *   0: on success
498*7917SReza.Sabdar@Sun.COM  *  -1: otherwise
499*7917SReza.Sabdar@Sun.COM  */
500*7917SReza.Sabdar@Sun.COM /*ARGSUSED*/
501*7917SReza.Sabdar@Sun.COM static void
common_set_target(ndmp_connection_t * connection,char * device,ushort_t controller,ushort_t sid,ushort_t lun)502*7917SReza.Sabdar@Sun.COM common_set_target(ndmp_connection_t *connection, char *device,
503*7917SReza.Sabdar@Sun.COM     ushort_t controller, ushort_t sid, ushort_t lun)
504*7917SReza.Sabdar@Sun.COM {
505*7917SReza.Sabdar@Sun.COM 	ndmp_scsi_set_target_reply reply;
506*7917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session = ndmp_get_client_data(connection);
507*7917SReza.Sabdar@Sun.COM 	int type;
508*7917SReza.Sabdar@Sun.COM 
509*7917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
510*7917SReza.Sabdar@Sun.COM 
511*7917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_is_open == -1) {
512*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_DEV_NOT_OPEN_ERR;
513*7917SReza.Sabdar@Sun.COM 	} else if (!scsi_dev_exists(session->ns_scsi.sd_adapter_name, sid,
514*7917SReza.Sabdar@Sun.COM 	    lun)) {
515*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "No such SCSI device: target %d lun %d.",
516*7917SReza.Sabdar@Sun.COM 		    sid, lun);
517*7917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NO_DEVICE_ERR;
518*7917SReza.Sabdar@Sun.COM 	} else {
519*7917SReza.Sabdar@Sun.COM 		type = scsi_get_devtype(session->ns_scsi.sd_adapter_name, sid,
520*7917SReza.Sabdar@Sun.COM 		    lun);
521*7917SReza.Sabdar@Sun.COM 		if (type != DTYPE_SEQUENTIAL && type != DTYPE_CHANGER) {
522*7917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
523*7917SReza.Sabdar@Sun.COM 			    "Not a tape or robot device: target %d lun %d.",
524*7917SReza.Sabdar@Sun.COM 			    sid, lun);
525*7917SReza.Sabdar@Sun.COM 			reply.error = NDMP_ILLEGAL_ARGS_ERR;
526*7917SReza.Sabdar@Sun.COM 		}
527*7917SReza.Sabdar@Sun.COM 	}
528*7917SReza.Sabdar@Sun.COM 
529*7917SReza.Sabdar@Sun.COM 	if (reply.error != NDMP_NO_ERR) {
530*7917SReza.Sabdar@Sun.COM 		ndmp_send_reply(connection, (void *) &reply,
531*7917SReza.Sabdar@Sun.COM 		    "sending scsi_set_target reply");
532*7917SReza.Sabdar@Sun.COM 		return;
533*7917SReza.Sabdar@Sun.COM 	}
534*7917SReza.Sabdar@Sun.COM 
535*7917SReza.Sabdar@Sun.COM 	/*
536*7917SReza.Sabdar@Sun.COM 	 * The open_list must be updated if the SID or LUN are going to be
537*7917SReza.Sabdar@Sun.COM 	 * changed.  Close uses the same SID & LUN for removing the entry
538*7917SReza.Sabdar@Sun.COM 	 * from the open_list.
539*7917SReza.Sabdar@Sun.COM 	 */
540*7917SReza.Sabdar@Sun.COM 	if (sid != session->ns_scsi.sd_sid || lun != session->ns_scsi.sd_lun) {
541*7917SReza.Sabdar@Sun.COM 		switch (ndmp_open_list_add(connection,
542*7917SReza.Sabdar@Sun.COM 		    session->ns_scsi.sd_adapter_name, sid, lun, 0)) {
543*7917SReza.Sabdar@Sun.COM 		case 0:
544*7917SReza.Sabdar@Sun.COM 			(void) ndmp_open_list_del(session->
545*7917SReza.Sabdar@Sun.COM 			    ns_scsi.sd_adapter_name, session->ns_scsi.sd_sid,
546*7917SReza.Sabdar@Sun.COM 			    session->ns_scsi.sd_lun);
547*7917SReza.Sabdar@Sun.COM 			break;
548*7917SReza.Sabdar@Sun.COM 		case EBUSY:
549*7917SReza.Sabdar@Sun.COM 			reply.error = NDMP_DEVICE_BUSY_ERR;
550*7917SReza.Sabdar@Sun.COM 			break;
551*7917SReza.Sabdar@Sun.COM 		case ENOMEM:
552*7917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NO_MEM_ERR;
553*7917SReza.Sabdar@Sun.COM 			break;
554*7917SReza.Sabdar@Sun.COM 		default:
555*7917SReza.Sabdar@Sun.COM 			reply.error = NDMP_IO_ERR;
556*7917SReza.Sabdar@Sun.COM 		}
557*7917SReza.Sabdar@Sun.COM 	}
558*7917SReza.Sabdar@Sun.COM 
559*7917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR) {
560*7917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Updated sid %d lun %d", sid, lun);
561*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_sid = sid;
562*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_lun = lun;
563*7917SReza.Sabdar@Sun.COM 		session->ns_scsi.sd_valid_target_set = TRUE;
564*7917SReza.Sabdar@Sun.COM 	}
565*7917SReza.Sabdar@Sun.COM 
566*7917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
567*7917SReza.Sabdar@Sun.COM 	    "sending scsi_set_target reply");
568*7917SReza.Sabdar@Sun.COM }
569*7917SReza.Sabdar@Sun.COM 
570*7917SReza.Sabdar@Sun.COM /*
571*7917SReza.Sabdar@Sun.COM  * scsi_find_sid_lun
572*7917SReza.Sabdar@Sun.COM  *
573*7917SReza.Sabdar@Sun.COM  * gets the adapter, and returns the sid and lun number
574*7917SReza.Sabdar@Sun.COM  */
575*7917SReza.Sabdar@Sun.COM void
scsi_find_sid_lun(scsi_adapter_t * sa,char * devname,int * sid,int * lun)576*7917SReza.Sabdar@Sun.COM scsi_find_sid_lun(scsi_adapter_t *sa, char *devname, int *sid, int *lun)
577*7917SReza.Sabdar@Sun.COM {
578*7917SReza.Sabdar@Sun.COM 	scsi_link_t *sl;
579*7917SReza.Sabdar@Sun.COM 	char *name;
580*7917SReza.Sabdar@Sun.COM 
581*7917SReza.Sabdar@Sun.COM 	for (sl = sa->sa_link_head.sl_next; sl && sl != &sa->sa_link_head;
582*7917SReza.Sabdar@Sun.COM 	    sl = sl->sl_next) {
583*7917SReza.Sabdar@Sun.COM 		name = sasd_slink_name(sl);
584*7917SReza.Sabdar@Sun.COM 		if (strcmp(devname, name) == 0) {
585*7917SReza.Sabdar@Sun.COM 			*sid = sl->sl_sid;
586*7917SReza.Sabdar@Sun.COM 			*lun = sl->sl_lun;
587*7917SReza.Sabdar@Sun.COM 			return;
588*7917SReza.Sabdar@Sun.COM 		}
589*7917SReza.Sabdar@Sun.COM 	}
590*7917SReza.Sabdar@Sun.COM 
591*7917SReza.Sabdar@Sun.COM 	*sid = -1;
592*7917SReza.Sabdar@Sun.COM 	*lun = -1;
593*7917SReza.Sabdar@Sun.COM }
594