9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Enclosure Services Devices, SAF-TE Enclosure Routines
24 *
25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29 #pragma ident "%Z%%M% %I% %E% SMI"
30
31 #include <sys/modctl.h>
32 #include <sys/file.h>
33 #include <sys/scsi/scsi.h>
34 #include <sys/stat.h>
35 #include <sys/scsi/targets/sesio.h>
36 #include <sys/scsi/targets/ses.h>
37
38
39 static int set_objstat_sel(ses_softc_t *, ses_objarg *, int);
40 static int wrbuf16(ses_softc_t *, uchar_t, uchar_t, uchar_t, uchar_t, int);
41 static void wrslot_stat(ses_softc_t *, int);
42 static int perf_slotop(ses_softc_t *, uchar_t, uchar_t, int);
43
44 #define ALL_ENC_STAT \
45 (ENCSTAT_CRITICAL|ENCSTAT_UNRECOV|ENCSTAT_NONCRITICAL|ENCSTAT_INFO)
46
47 #define SCRATCH 64
48 #define NPSEUDO_THERM 1
49 #define NPSEUDO_ALARM 1
50 struct scfg {
95 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::flag2))
96 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::pwroff))
97 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::slotoff))
98 #endif
99
100 static int
101 safte_getconfig(ses_softc_t *ssc)
102 {
103 struct scfg *cfg;
104 int err;
105 Uscmd local, *lp = &local;
106 char rqbuf[SENSE_LENGTH], *sdata;
107 static char cdb[CDB_GROUP1] =
108 { SCMD_READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SCRATCH, 0 };
109
110 cfg = ssc->ses_private;
111 if (cfg == NULL)
112 return (ENXIO);
113
114 sdata = kmem_alloc(SCRATCH, KM_SLEEP);
115 if (sdata == NULL)
116 return (ENOMEM);
117
118 lp->uscsi_flags = USCSI_READ|USCSI_RQENABLE;
119 lp->uscsi_timeout = ses_io_time;
120 lp->uscsi_cdb = cdb;
121 lp->uscsi_bufaddr = sdata;
122 lp->uscsi_buflen = SCRATCH;
123 lp->uscsi_cdblen = sizeof (cdb);
124 lp->uscsi_rqbuf = rqbuf;
125 lp->uscsi_rqlen = sizeof (rqbuf);
126
127 err = ses_runcmd(ssc, lp);
128 if (err) {
129 kmem_free(sdata, SCRATCH);
130 return (err);
131 }
132
133 if ((lp->uscsi_buflen - lp->uscsi_resid) < 6) {
134 SES_LOG(ssc, CE_NOTE, "Too little data (%ld) for configuration",
135 lp->uscsi_buflen - lp->uscsi_resid);
136 kmem_free(sdata, SCRATCH);
163 mutex_enter(&ssc->ses_devp->sd_mutex);
164 if (ssc->ses_nobjects) {
165 if (ssc->ses_objmap) {
166 kmem_free(ssc->ses_objmap,
167 ssc->ses_nobjects * sizeof (encobj));
168 ssc->ses_objmap = NULL;
169 }
170 ssc->ses_nobjects = 0;
171 }
172 if (ssc->ses_private) {
173 kmem_free(ssc->ses_private, SAFTE_PRIVATE);
174 ssc->ses_private = NULL;
175 }
176 mutex_exit(&ssc->ses_devp->sd_mutex);
177 return (0);
178 }
179
180 mutex_enter(&ssc->ses_devp->sd_mutex);
181 if (ssc->ses_private == NULL) {
182 ssc->ses_private = kmem_zalloc(SAFTE_PRIVATE, KM_SLEEP);
183 if (ssc->ses_private == NULL) {
184 mutex_exit(&ssc->ses_devp->sd_mutex);
185 return (ENOMEM);
186 }
187 }
188
189 ssc->ses_nobjects = 0;
190 ssc->ses_encstat = 0;
191 mutex_exit(&ssc->ses_devp->sd_mutex);
192
193 if ((r = safte_getconfig(ssc)) != 0) {
194 return (r);
195 }
196
197 /*
198 * The number of objects here, as well as that reported by the
199 * READ_BUFFER/GET_CONFIG call, are the over-temperature flags (15)
200 * that get reported during READ_BUFFER/READ_ENC_STATUS.
201 */
202 mutex_enter(&ssc->ses_devp->sd_mutex);
203 cc = ssc->ses_private;
204 ssc->ses_nobjects = cc->Nfans + cc->Npwr + cc->Nslots + cc->DoorLock +
205 cc->Ntherm + cc->Nspkrs + NPSEUDO_THERM + NPSEUDO_ALARM;
206 ssc->ses_objmap = (encobj *)
|
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Enclosure Services Devices, SAF-TE Enclosure Routines
24 *
25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29 #include <sys/modctl.h>
30 #include <sys/file.h>
31 #include <sys/scsi/scsi.h>
32 #include <sys/stat.h>
33 #include <sys/scsi/targets/sesio.h>
34 #include <sys/scsi/targets/ses.h>
35
36
37 static int set_objstat_sel(ses_softc_t *, ses_objarg *, int);
38 static int wrbuf16(ses_softc_t *, uchar_t, uchar_t, uchar_t, uchar_t, int);
39 static void wrslot_stat(ses_softc_t *, int);
40 static int perf_slotop(ses_softc_t *, uchar_t, uchar_t, int);
41
42 #define ALL_ENC_STAT \
43 (ENCSTAT_CRITICAL|ENCSTAT_UNRECOV|ENCSTAT_NONCRITICAL|ENCSTAT_INFO)
44
45 #define SCRATCH 64
46 #define NPSEUDO_THERM 1
47 #define NPSEUDO_ALARM 1
48 struct scfg {
93 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::flag2))
94 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::pwroff))
95 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::slotoff))
96 #endif
97
98 static int
99 safte_getconfig(ses_softc_t *ssc)
100 {
101 struct scfg *cfg;
102 int err;
103 Uscmd local, *lp = &local;
104 char rqbuf[SENSE_LENGTH], *sdata;
105 static char cdb[CDB_GROUP1] =
106 { SCMD_READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SCRATCH, 0 };
107
108 cfg = ssc->ses_private;
109 if (cfg == NULL)
110 return (ENXIO);
111
112 sdata = kmem_alloc(SCRATCH, KM_SLEEP);
113
114 lp->uscsi_flags = USCSI_READ|USCSI_RQENABLE;
115 lp->uscsi_timeout = ses_io_time;
116 lp->uscsi_cdb = cdb;
117 lp->uscsi_bufaddr = sdata;
118 lp->uscsi_buflen = SCRATCH;
119 lp->uscsi_cdblen = sizeof (cdb);
120 lp->uscsi_rqbuf = rqbuf;
121 lp->uscsi_rqlen = sizeof (rqbuf);
122
123 err = ses_runcmd(ssc, lp);
124 if (err) {
125 kmem_free(sdata, SCRATCH);
126 return (err);
127 }
128
129 if ((lp->uscsi_buflen - lp->uscsi_resid) < 6) {
130 SES_LOG(ssc, CE_NOTE, "Too little data (%ld) for configuration",
131 lp->uscsi_buflen - lp->uscsi_resid);
132 kmem_free(sdata, SCRATCH);
159 mutex_enter(&ssc->ses_devp->sd_mutex);
160 if (ssc->ses_nobjects) {
161 if (ssc->ses_objmap) {
162 kmem_free(ssc->ses_objmap,
163 ssc->ses_nobjects * sizeof (encobj));
164 ssc->ses_objmap = NULL;
165 }
166 ssc->ses_nobjects = 0;
167 }
168 if (ssc->ses_private) {
169 kmem_free(ssc->ses_private, SAFTE_PRIVATE);
170 ssc->ses_private = NULL;
171 }
172 mutex_exit(&ssc->ses_devp->sd_mutex);
173 return (0);
174 }
175
176 mutex_enter(&ssc->ses_devp->sd_mutex);
177 if (ssc->ses_private == NULL) {
178 ssc->ses_private = kmem_zalloc(SAFTE_PRIVATE, KM_SLEEP);
179 }
180
181 ssc->ses_nobjects = 0;
182 ssc->ses_encstat = 0;
183 mutex_exit(&ssc->ses_devp->sd_mutex);
184
185 if ((r = safte_getconfig(ssc)) != 0) {
186 return (r);
187 }
188
189 /*
190 * The number of objects here, as well as that reported by the
191 * READ_BUFFER/GET_CONFIG call, are the over-temperature flags (15)
192 * that get reported during READ_BUFFER/READ_ENC_STATUS.
193 */
194 mutex_enter(&ssc->ses_devp->sd_mutex);
195 cc = ssc->ses_private;
196 ssc->ses_nobjects = cc->Nfans + cc->Npwr + cc->Nslots + cc->DoorLock +
197 cc->Ntherm + cc->Nspkrs + NPSEUDO_THERM + NPSEUDO_ALARM;
198 ssc->ses_objmap = (encobj *)
|