24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock/*
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * CDDL HEADER START
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * The contents of this file are subject to the terms of the
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * Common Development and Distribution License (the "License").
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * You may not use this file except in compliance with the License.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * or http://www.opensolaris.org/os/licensing.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * See the License for the specific language governing permissions
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * and limitations under the License.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * When distributing Covered Code, include this CDDL HEADER in each
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * If applicable, add the following below this CDDL HEADER, with the
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * fields enclosed by brackets "[]" replaced with your own identifying
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * information: Portions Copyright [yyyy] [name of copyright owner]
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * CDDL HEADER END
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock */
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock/*
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * Use is subject to license terms.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock */
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock#pragma ident "%Z%%M% %I% %E% SMI"
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock/*
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * SCSI simulator.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * For testing purposes, we need a way to simulate arbitrary SCSI responses. A
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * completely flexible SCSI simulation language would be a large undertaking,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * given the number of possible outcomes. Instead, we opt for the simpler route
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * of using a shared object which implements versions of these functions.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock *
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * If a shared object doesn't implement a given function, or if the function
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * returns non-zero, then the simulator will provide a suitable response
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock * indicating the functionality isn't supported.
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock */
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock#include <libdiskstatus.h>
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock#include "ds_scsi.h"
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock#include "ds_scsi_sim.h"
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockstatic int
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockcheck_invalid_code(int ret, void *rqbuf)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (ret != 0) {
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock struct scsi_extended_sense *sensep = rqbuf;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock sensep->es_key = KEY_ILLEGAL_REQUEST;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock sensep->es_add_len = 6;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock sensep->es_code = CODE_FMT_FIXED_CURRENT;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock sensep->es_add_code = ASC_INVALID_OPCODE;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock sensep->es_qual_code = ASCQ_INVALID_OPCODE;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock }
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (ret);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_mode_sense_f)(int, int, caddr_t, int, scsi_ms_header_t *,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_mode_sense(void *hdl, int page_code, int page_control,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock caddr_t page_data, int page_size, scsi_ms_header_t *header,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_mode_sense_f dscsi_mode_sense;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_mode_sense = (scsi_mode_sense_f)dlsym(hdl, "scsi_mode_sense");
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_mode_sense != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_mode_sense)(page_code, page_control, page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock page_size, header, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_mode_sense_10_f)(int, int, caddr_t, int,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_ms_header_g1_t *, void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_mode_sense_10(void *hdl, int page_code, int page_control,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock caddr_t page_data, int page_size, scsi_ms_header_g1_t *header,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_mode_sense_10_f dscsi_mode_sense_10;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_mode_sense_10 = (scsi_mode_sense_10_f)dlsym(hdl,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock "scsi_mode_sense_10");
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_mode_sense_10 != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_mode_sense_10)(page_code, page_control, page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock page_size, header, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_mode_select_f)(int, int, caddr_t, int, scsi_ms_header_t *,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_mode_select(void *hdl, int page_code, int options, caddr_t page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int page_size, scsi_ms_header_t *header, void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_mode_select_f dscsi_mode_select;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_mode_select = (scsi_mode_select_f)(dlsym(hdl,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock "scsi_mode_select"));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_mode_select != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_mode_select)(page_code, options, page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock page_size, header, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_mode_select_10_f)(int, int, caddr_t, int,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_ms_header_g1_t *, void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_mode_select_10(void *hdl, int page_code, int options,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock caddr_t page_data, int page_size, scsi_ms_header_g1_t *header,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_mode_select_10_f dscsi_mode_select_10;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_mode_select_10 = (scsi_mode_select_10_f)dlsym(hdl,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock "scsi_mode_select_10");
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_mode_select_10 != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_mode_select_10)(page_code, options, page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock page_size, header, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_log_sense_f)(int, int, caddr_t, int, void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_log_sense(void *hdl, int page_code, int page_control,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock caddr_t page_data, int page_size, void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_log_sense_f dscsi_log_sense;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_log_sense = (scsi_log_sense_f)dlsym(hdl, "scsi_log_sense");
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_log_sense != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_log_sense)(page_code, page_control, page_data,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock page_size, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocktypedef int (*scsi_request_sense_f)(caddr_t, int, void *, int *);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrockint
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrocksimscsi_request_sense(void *hdl, caddr_t buf, int buflen,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock void *rqbuf, int *rqblen)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock{
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock scsi_request_sense_f dscsi_request_sense;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock int ret = -1;
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock dscsi_request_sense = (scsi_request_sense_f)dlsym(hdl,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock "scsi_request_sense");
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock if (dscsi_request_sense != NULL)
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock ret = (*dscsi_request_sense)(buf, buflen, rqbuf, rqblen);
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (check_invalid_code(ret, rqbuf));
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock}