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 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 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 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 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 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 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 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 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 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 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 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 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 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