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