xref: /illumos-gate/usr/src/lib/fm/libdiskstatus/common/ds_scsi_sim.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
1*24db4641Seschrock /*
2*24db4641Seschrock  * CDDL HEADER START
3*24db4641Seschrock  *
4*24db4641Seschrock  * The contents of this file are subject to the terms of the
5*24db4641Seschrock  * Common Development and Distribution License (the "License").
6*24db4641Seschrock  * You may not use this file except in compliance with the License.
7*24db4641Seschrock  *
8*24db4641Seschrock  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*24db4641Seschrock  * or http://www.opensolaris.org/os/licensing.
10*24db4641Seschrock  * See the License for the specific language governing permissions
11*24db4641Seschrock  * and limitations under the License.
12*24db4641Seschrock  *
13*24db4641Seschrock  * When distributing Covered Code, include this CDDL HEADER in each
14*24db4641Seschrock  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*24db4641Seschrock  * If applicable, add the following below this CDDL HEADER, with the
16*24db4641Seschrock  * fields enclosed by brackets "[]" replaced with your own identifying
17*24db4641Seschrock  * information: Portions Copyright [yyyy] [name of copyright owner]
18*24db4641Seschrock  *
19*24db4641Seschrock  * CDDL HEADER END
20*24db4641Seschrock  */
21*24db4641Seschrock /*
22*24db4641Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*24db4641Seschrock  * Use is subject to license terms.
24*24db4641Seschrock  */
25*24db4641Seschrock 
26*24db4641Seschrock /*
27*24db4641Seschrock  * SCSI simulator.
28*24db4641Seschrock  *
29*24db4641Seschrock  * For testing purposes, we need a way to simulate arbitrary SCSI responses.  A
30*24db4641Seschrock  * completely flexible SCSI simulation language would be a large undertaking,
31*24db4641Seschrock  * given the number of possible outcomes.  Instead, we opt for the simpler route
32*24db4641Seschrock  * of using a shared object which implements versions of these functions.
33*24db4641Seschrock  *
34*24db4641Seschrock  * If a shared object doesn't implement a given function, or if the function
35*24db4641Seschrock  * returns non-zero, then the simulator will provide a suitable response
36*24db4641Seschrock  * indicating the functionality isn't supported.
37*24db4641Seschrock  */
38*24db4641Seschrock 
39*24db4641Seschrock #include <libdiskstatus.h>
40*24db4641Seschrock 
41*24db4641Seschrock #include "ds_scsi.h"
42*24db4641Seschrock #include "ds_scsi_sim.h"
43*24db4641Seschrock 
44*24db4641Seschrock static int
check_invalid_code(int ret,void * rqbuf)45*24db4641Seschrock check_invalid_code(int ret, void *rqbuf)
46*24db4641Seschrock {
47*24db4641Seschrock 	if (ret != 0) {
48*24db4641Seschrock 		struct scsi_extended_sense *sensep = rqbuf;
49*24db4641Seschrock 
50*24db4641Seschrock 		sensep->es_key = KEY_ILLEGAL_REQUEST;
51*24db4641Seschrock 		sensep->es_add_len = 6;
52*24db4641Seschrock 		sensep->es_code = CODE_FMT_FIXED_CURRENT;
53*24db4641Seschrock 		sensep->es_add_code = ASC_INVALID_OPCODE;
54*24db4641Seschrock 		sensep->es_qual_code = ASCQ_INVALID_OPCODE;
55*24db4641Seschrock 		ret = -1;
56*24db4641Seschrock 	}
57*24db4641Seschrock 
58*24db4641Seschrock 	return (ret);
59*24db4641Seschrock }
60*24db4641Seschrock 
61*24db4641Seschrock typedef int (*scsi_mode_sense_f)(int, int, caddr_t, int, scsi_ms_header_t *,
62*24db4641Seschrock     void *, int *);
63*24db4641Seschrock 
64*24db4641Seschrock int
simscsi_mode_sense(void * hdl,int page_code,int page_control,caddr_t page_data,int page_size,scsi_ms_header_t * header,void * rqbuf,int * rqblen)65*24db4641Seschrock simscsi_mode_sense(void *hdl, int page_code, int page_control,
66*24db4641Seschrock     caddr_t page_data, int page_size, scsi_ms_header_t *header,
67*24db4641Seschrock     void *rqbuf, int *rqblen)
68*24db4641Seschrock {
69*24db4641Seschrock 	scsi_mode_sense_f dscsi_mode_sense;
70*24db4641Seschrock 	int ret = -1;
71*24db4641Seschrock 
72*24db4641Seschrock 	dscsi_mode_sense = (scsi_mode_sense_f)dlsym(hdl, "scsi_mode_sense");
73*24db4641Seschrock 
74*24db4641Seschrock 	if (dscsi_mode_sense != NULL)
75*24db4641Seschrock 		ret = (*dscsi_mode_sense)(page_code, page_control, page_data,
76*24db4641Seschrock 		    page_size, header, rqbuf, rqblen);
77*24db4641Seschrock 
78*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
79*24db4641Seschrock }
80*24db4641Seschrock 
81*24db4641Seschrock typedef int (*scsi_mode_sense_10_f)(int, int, caddr_t, int,
82*24db4641Seschrock     scsi_ms_header_g1_t *, void *, int *);
83*24db4641Seschrock 
84*24db4641Seschrock int
simscsi_mode_sense_10(void * hdl,int page_code,int page_control,caddr_t page_data,int page_size,scsi_ms_header_g1_t * header,void * rqbuf,int * rqblen)85*24db4641Seschrock simscsi_mode_sense_10(void *hdl, int page_code, int page_control,
86*24db4641Seschrock     caddr_t page_data, int page_size, scsi_ms_header_g1_t *header,
87*24db4641Seschrock     void *rqbuf, int *rqblen)
88*24db4641Seschrock {
89*24db4641Seschrock 	scsi_mode_sense_10_f dscsi_mode_sense_10;
90*24db4641Seschrock 	int ret = -1;
91*24db4641Seschrock 
92*24db4641Seschrock 	dscsi_mode_sense_10 = (scsi_mode_sense_10_f)dlsym(hdl,
93*24db4641Seschrock 	    "scsi_mode_sense_10");
94*24db4641Seschrock 
95*24db4641Seschrock 	if (dscsi_mode_sense_10 != NULL)
96*24db4641Seschrock 		ret = (*dscsi_mode_sense_10)(page_code, page_control, page_data,
97*24db4641Seschrock 		    page_size, header, rqbuf, rqblen);
98*24db4641Seschrock 
99*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
100*24db4641Seschrock }
101*24db4641Seschrock 
102*24db4641Seschrock typedef int (*scsi_mode_select_f)(int, int, caddr_t, int, scsi_ms_header_t *,
103*24db4641Seschrock     void *, int *);
104*24db4641Seschrock 
105*24db4641Seschrock int
simscsi_mode_select(void * hdl,int page_code,int options,caddr_t page_data,int page_size,scsi_ms_header_t * header,void * rqbuf,int * rqblen)106*24db4641Seschrock simscsi_mode_select(void *hdl, int page_code, int options, caddr_t page_data,
107*24db4641Seschrock     int page_size, scsi_ms_header_t *header, void *rqbuf, int *rqblen)
108*24db4641Seschrock {
109*24db4641Seschrock 	scsi_mode_select_f dscsi_mode_select;
110*24db4641Seschrock 	int ret = -1;
111*24db4641Seschrock 
112*24db4641Seschrock 	dscsi_mode_select = (scsi_mode_select_f)(dlsym(hdl,
113*24db4641Seschrock 	    "scsi_mode_select"));
114*24db4641Seschrock 
115*24db4641Seschrock 	if (dscsi_mode_select != NULL)
116*24db4641Seschrock 		ret = (*dscsi_mode_select)(page_code, options, page_data,
117*24db4641Seschrock 		    page_size, header, rqbuf, rqblen);
118*24db4641Seschrock 
119*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
120*24db4641Seschrock }
121*24db4641Seschrock 
122*24db4641Seschrock typedef int (*scsi_mode_select_10_f)(int, int, caddr_t, int,
123*24db4641Seschrock     scsi_ms_header_g1_t *, void *, int *);
124*24db4641Seschrock 
125*24db4641Seschrock int
simscsi_mode_select_10(void * hdl,int page_code,int options,caddr_t page_data,int page_size,scsi_ms_header_g1_t * header,void * rqbuf,int * rqblen)126*24db4641Seschrock simscsi_mode_select_10(void *hdl, int page_code, int options,
127*24db4641Seschrock     caddr_t page_data, int page_size, scsi_ms_header_g1_t *header,
128*24db4641Seschrock     void *rqbuf, int *rqblen)
129*24db4641Seschrock {
130*24db4641Seschrock 	scsi_mode_select_10_f dscsi_mode_select_10;
131*24db4641Seschrock 	int ret = -1;
132*24db4641Seschrock 
133*24db4641Seschrock 	dscsi_mode_select_10 = (scsi_mode_select_10_f)dlsym(hdl,
134*24db4641Seschrock 	    "scsi_mode_select_10");
135*24db4641Seschrock 
136*24db4641Seschrock 	if (dscsi_mode_select_10 != NULL)
137*24db4641Seschrock 		ret = (*dscsi_mode_select_10)(page_code, options, page_data,
138*24db4641Seschrock 		    page_size, header, rqbuf, rqblen);
139*24db4641Seschrock 
140*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
141*24db4641Seschrock }
142*24db4641Seschrock 
143*24db4641Seschrock typedef int (*scsi_log_sense_f)(int, int, caddr_t, int, void *, int *);
144*24db4641Seschrock 
145*24db4641Seschrock int
simscsi_log_sense(void * hdl,int page_code,int page_control,caddr_t page_data,int page_size,void * rqbuf,int * rqblen)146*24db4641Seschrock simscsi_log_sense(void *hdl, int page_code, int page_control,
147*24db4641Seschrock     caddr_t page_data, int page_size, void *rqbuf, int *rqblen)
148*24db4641Seschrock {
149*24db4641Seschrock 	scsi_log_sense_f dscsi_log_sense;
150*24db4641Seschrock 	int ret = -1;
151*24db4641Seschrock 
152*24db4641Seschrock 	dscsi_log_sense = (scsi_log_sense_f)dlsym(hdl, "scsi_log_sense");
153*24db4641Seschrock 
154*24db4641Seschrock 	if (dscsi_log_sense != NULL)
155*24db4641Seschrock 		ret = (*dscsi_log_sense)(page_code, page_control, page_data,
156*24db4641Seschrock 		    page_size, rqbuf, rqblen);
157*24db4641Seschrock 
158*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
159*24db4641Seschrock }
160*24db4641Seschrock 
161*24db4641Seschrock typedef int (*scsi_request_sense_f)(caddr_t, int, void *, int *);
162*24db4641Seschrock 
163*24db4641Seschrock int
simscsi_request_sense(void * hdl,caddr_t buf,int buflen,void * rqbuf,int * rqblen)164*24db4641Seschrock simscsi_request_sense(void *hdl, caddr_t buf, int buflen,
165*24db4641Seschrock     void *rqbuf, int *rqblen)
166*24db4641Seschrock {
167*24db4641Seschrock 	scsi_request_sense_f dscsi_request_sense;
168*24db4641Seschrock 	int ret = -1;
169*24db4641Seschrock 
170*24db4641Seschrock 	dscsi_request_sense = (scsi_request_sense_f)dlsym(hdl,
171*24db4641Seschrock 	    "scsi_request_sense");
172*24db4641Seschrock 
173*24db4641Seschrock 	if (dscsi_request_sense != NULL)
174*24db4641Seschrock 		ret = (*dscsi_request_sense)(buf, buflen, rqbuf, rqblen);
175*24db4641Seschrock 
176*24db4641Seschrock 	return (check_invalid_code(ret, rqbuf));
177*24db4641Seschrock }
178