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