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