1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2000 Matthew Jacob
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30
31 #include <sys/conf.h>
32 #include <sys/errno.h>
33 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/mutex.h>
36 #include <sys/queue.h>
37 #include <sys/sx.h>
38 #include <sys/systm.h>
39 #include <sys/sysctl.h>
40 #include <sys/types.h>
41
42 #include <cam/cam.h>
43 #include <cam/cam_ccb.h>
44 #include <cam/cam_periph.h>
45
46 #include <cam/scsi/scsi_enc.h>
47 #include <cam/scsi/scsi_enc_internal.h>
48 #include <cam/scsi/scsi_message.h>
49
50 /*
51 * SAF-TE Type Device Emulation
52 */
53
54 static int safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag);
55
56 #define ALL_ENC_STAT (SES_ENCSTAT_CRITICAL | SES_ENCSTAT_UNRECOV | \
57 SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
58 /*
59 * SAF-TE specific defines- Mandatory ones only...
60 */
61
62 /*
63 * READ BUFFER ('get' commands) IDs- placed in offset 2 of cdb
64 */
65 #define SAFTE_RD_RDCFG 0x00 /* read enclosure configuration */
66 #define SAFTE_RD_RDESTS 0x01 /* read enclosure status */
67 #define SAFTE_RD_RDDSTS 0x04 /* read drive slot status */
68 #define SAFTE_RD_RDGFLG 0x05 /* read global flags */
69
70 /*
71 * WRITE BUFFER ('set' commands) IDs- placed in offset 0 of databuf
72 */
73 #define SAFTE_WT_DSTAT 0x10 /* write device slot status */
74 #define SAFTE_WT_SLTOP 0x12 /* perform slot operation */
75 #define SAFTE_WT_FANSPD 0x13 /* set fan speed */
76 #define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */
77 #define SAFTE_WT_GLOBAL 0x15 /* send global command */
78
79 #define SAFT_SCRATCH 64
80 #define SCSZ 0x8000
81
82 typedef enum {
83 SAFTE_UPDATE_NONE,
84 SAFTE_UPDATE_READCONFIG,
85 SAFTE_UPDATE_READGFLAGS,
86 SAFTE_UPDATE_READENCSTATUS,
87 SAFTE_UPDATE_READSLOTSTATUS,
88 SAFTE_PROCESS_CONTROL_REQS,
89 SAFTE_NUM_UPDATE_STATES
90 } safte_update_action;
91
92 static fsm_fill_handler_t safte_fill_read_buf_io;
93 static fsm_fill_handler_t safte_fill_control_request;
94 static fsm_done_handler_t safte_process_config;
95 static fsm_done_handler_t safte_process_gflags;
96 static fsm_done_handler_t safte_process_status;
97 static fsm_done_handler_t safte_process_slotstatus;
98 static fsm_done_handler_t safte_process_control_request;
99
100 static struct enc_fsm_state enc_fsm_states[SAFTE_NUM_UPDATE_STATES] =
101 {
102 { "SAFTE_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
103 {
104 "SAFTE_UPDATE_READCONFIG",
105 SAFTE_RD_RDCFG,
106 SAFT_SCRATCH,
107 60 * 1000,
108 safte_fill_read_buf_io,
109 safte_process_config,
110 enc_error
111 },
112 {
113 "SAFTE_UPDATE_READGFLAGS",
114 SAFTE_RD_RDGFLG,
115 16,
116 60 * 1000,
117 safte_fill_read_buf_io,
118 safte_process_gflags,
119 enc_error
120 },
121 {
122 "SAFTE_UPDATE_READENCSTATUS",
123 SAFTE_RD_RDESTS,
124 SCSZ,
125 60 * 1000,
126 safte_fill_read_buf_io,
127 safte_process_status,
128 enc_error
129 },
130 {
131 "SAFTE_UPDATE_READSLOTSTATUS",
132 SAFTE_RD_RDDSTS,
133 SCSZ,
134 60 * 1000,
135 safte_fill_read_buf_io,
136 safte_process_slotstatus,
137 enc_error
138 },
139 {
140 "SAFTE_PROCESS_CONTROL_REQS",
141 0,
142 SCSZ,
143 60 * 1000,
144 safte_fill_control_request,
145 safte_process_control_request,
146 enc_error
147 }
148 };
149
150 typedef struct safte_control_request {
151 int elm_idx;
152 uint8_t elm_stat[4];
153 int result;
154 TAILQ_ENTRY(safte_control_request) links;
155 } safte_control_request_t;
156 TAILQ_HEAD(safte_control_reqlist, safte_control_request);
157 typedef struct safte_control_reqlist safte_control_reqlist_t;
158 enum {
159 SES_SETSTATUS_ENC_IDX = -1
160 };
161
162 static void
safte_terminate_control_requests(safte_control_reqlist_t * reqlist,int result)163 safte_terminate_control_requests(safte_control_reqlist_t *reqlist, int result)
164 {
165 safte_control_request_t *req;
166
167 while ((req = TAILQ_FIRST(reqlist)) != NULL) {
168 TAILQ_REMOVE(reqlist, req, links);
169 req->result = result;
170 wakeup(req);
171 }
172 }
173
174 struct scfg {
175 /*
176 * Cached Configuration
177 */
178 uint8_t Nfans; /* Number of Fans */
179 uint8_t Npwr; /* Number of Power Supplies */
180 uint8_t Nslots; /* Number of Device Slots */
181 uint8_t DoorLock; /* Door Lock Installed */
182 uint8_t Ntherm; /* Number of Temperature Sensors */
183 uint8_t Nspkrs; /* Number of Speakers */
184 uint8_t Ntstats; /* Number of Thermostats */
185 /*
186 * Cached Flag Bytes for Global Status
187 */
188 uint8_t flag1;
189 uint8_t flag2;
190 /*
191 * What object index ID is where various slots start.
192 */
193 uint8_t pwroff;
194 uint8_t slotoff;
195 #define SAFT_ALARM_OFFSET(cc) (cc)->slotoff - 1
196
197 encioc_enc_status_t adm_status;
198 encioc_enc_status_t enc_status;
199 encioc_enc_status_t slot_status;
200
201 safte_control_reqlist_t requests;
202 safte_control_request_t *current_request;
203 int current_request_stage;
204 int current_request_stages;
205 };
206
207 #define SAFT_FLG1_ALARM 0x1
208 #define SAFT_FLG1_GLOBFAIL 0x2
209 #define SAFT_FLG1_GLOBWARN 0x4
210 #define SAFT_FLG1_ENCPWROFF 0x8
211 #define SAFT_FLG1_ENCFANFAIL 0x10
212 #define SAFT_FLG1_ENCPWRFAIL 0x20
213 #define SAFT_FLG1_ENCDRVFAIL 0x40
214 #define SAFT_FLG1_ENCDRVWARN 0x80
215
216 #define SAFT_FLG2_LOCKDOOR 0x4
217 #define SAFT_PRIVATE sizeof (struct scfg)
218
219 static char *safte_2little = "Too Little Data Returned (%d) at line %d\n";
220 #define SAFT_BAIL(r, x) \
221 if ((r) >= (x)) { \
222 ENC_VLOG(enc, safte_2little, x, __LINE__);\
223 return (EIO); \
224 }
225
226 int emulate_array_devices = 1;
227 SYSCTL_INT(_kern_cam_enc, OID_AUTO, emulate_array_devices, CTLFLAG_RWTUN,
228 &emulate_array_devices, 0, "Emulate Array Devices for SAF-TE");
229
230 static int
safte_fill_read_buf_io(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t * buf)231 safte_fill_read_buf_io(enc_softc_t *enc, struct enc_fsm_state *state,
232 union ccb *ccb, uint8_t *buf)
233 {
234
235 if (state->page_code != SAFTE_RD_RDCFG &&
236 enc->enc_cache.nelms == 0) {
237 enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
238 return (-1);
239 }
240
241 if (enc->enc_type == ENC_SEMB_SAFT) {
242 semb_read_buffer(&ccb->ataio, /*retries*/5,
243 NULL, MSG_SIMPLE_Q_TAG,
244 state->page_code, buf, state->buf_size,
245 state->timeout);
246 } else {
247 scsi_read_buffer(&ccb->csio, /*retries*/5,
248 NULL, MSG_SIMPLE_Q_TAG, 1,
249 state->page_code, 0, buf, state->buf_size,
250 SSD_FULL_SIZE, state->timeout);
251 }
252 return (0);
253 }
254
255 static int
safte_process_config(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t ** bufp,int error,int xfer_len)256 safte_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
257 union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
258 {
259 struct scfg *cfg;
260 uint8_t *buf = *bufp;
261 int i, r;
262
263 cfg = enc->enc_private;
264 if (cfg == NULL)
265 return (ENXIO);
266 if (error != 0)
267 return (error);
268 if (xfer_len < 6) {
269 ENC_VLOG(enc, "too little data (%d) for configuration\n",
270 xfer_len);
271 return (EIO);
272 }
273 cfg->Nfans = buf[0];
274 cfg->Npwr = buf[1];
275 cfg->Nslots = buf[2];
276 cfg->DoorLock = buf[3];
277 cfg->Ntherm = buf[4];
278 cfg->Nspkrs = buf[5];
279 if (xfer_len >= 7)
280 cfg->Ntstats = buf[6] & 0x0f;
281 else
282 cfg->Ntstats = 0;
283 ENC_VLOG(enc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
284 "Ntstats %d\n",
285 cfg->Nfans, cfg->Npwr, cfg->Nslots, cfg->DoorLock, cfg->Ntherm,
286 cfg->Nspkrs, cfg->Ntstats);
287
288 enc->enc_cache.nelms = cfg->Nfans + cfg->Npwr + cfg->Nslots +
289 cfg->DoorLock + cfg->Ntherm + cfg->Nspkrs + cfg->Ntstats + 1;
290 ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
291 enc->enc_cache.elm_map =
292 malloc(enc->enc_cache.nelms * sizeof(enc_element_t),
293 M_SCSIENC, M_WAITOK|M_ZERO);
294
295 r = 0;
296 /*
297 * Note that this is all arranged for the convenience
298 * in later fetches of status.
299 */
300 for (i = 0; i < cfg->Nfans; i++)
301 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_FAN;
302 cfg->pwroff = (uint8_t) r;
303 for (i = 0; i < cfg->Npwr; i++)
304 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_POWER;
305 for (i = 0; i < cfg->DoorLock; i++)
306 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_DOORLOCK;
307 if (cfg->Nspkrs > 0)
308 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_ALARM;
309 for (i = 0; i < cfg->Ntherm; i++)
310 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_THERM;
311 for (i = 0; i <= cfg->Ntstats; i++)
312 enc->enc_cache.elm_map[r++].elm_type = ELMTYP_THERM;
313 cfg->slotoff = (uint8_t) r;
314 for (i = 0; i < cfg->Nslots; i++)
315 enc->enc_cache.elm_map[r++].elm_type =
316 emulate_array_devices ? ELMTYP_ARRAY_DEV :
317 ELMTYP_DEVICE;
318
319 enc_update_request(enc, SAFTE_UPDATE_READGFLAGS);
320 enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
321 enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
322
323 return (0);
324 }
325
326 static int
safte_process_gflags(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t ** bufp,int error,int xfer_len)327 safte_process_gflags(enc_softc_t *enc, struct enc_fsm_state *state,
328 union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
329 {
330 struct scfg *cfg;
331 uint8_t *buf = *bufp;
332
333 cfg = enc->enc_private;
334 if (cfg == NULL)
335 return (ENXIO);
336 if (error != 0)
337 return (error);
338 SAFT_BAIL(3, xfer_len);
339 cfg->flag1 = buf[1];
340 cfg->flag2 = buf[2];
341
342 cfg->adm_status = 0;
343 if (cfg->flag1 & SAFT_FLG1_GLOBFAIL)
344 cfg->adm_status |= SES_ENCSTAT_CRITICAL;
345 else if (cfg->flag1 & SAFT_FLG1_GLOBWARN)
346 cfg->adm_status |= SES_ENCSTAT_NONCRITICAL;
347
348 return (0);
349 }
350
351 static int
safte_process_status(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t ** bufp,int error,int xfer_len)352 safte_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
353 union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
354 {
355 struct scfg *cfg;
356 uint8_t *buf = *bufp;
357 int oid, r, i, nitems;
358 uint16_t tempflags;
359 enc_cache_t *cache = &enc->enc_cache;
360
361 cfg = enc->enc_private;
362 if (cfg == NULL)
363 return (ENXIO);
364 if (error != 0)
365 return (error);
366
367 oid = r = 0;
368 cfg->enc_status = 0;
369
370 for (nitems = i = 0; i < cfg->Nfans; i++) {
371 SAFT_BAIL(r, xfer_len);
372 /*
373 * 0 = Fan Operational
374 * 1 = Fan is malfunctioning
375 * 2 = Fan is not present
376 * 0x80 = Unknown or Not Reportable Status
377 */
378 cache->elm_map[oid].encstat[1] = 0; /* resvd */
379 cache->elm_map[oid].encstat[2] = 0; /* resvd */
380 if (cfg->flag1 & SAFT_FLG1_ENCFANFAIL)
381 cache->elm_map[oid].encstat[3] |= 0x40;
382 else
383 cache->elm_map[oid].encstat[3] &= ~0x40;
384 switch ((int)buf[r]) {
385 case 0:
386 nitems++;
387 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
388 if ((cache->elm_map[oid].encstat[3] & 0x37) == 0)
389 cache->elm_map[oid].encstat[3] |= 0x27;
390 break;
391
392 case 1:
393 cache->elm_map[oid].encstat[0] =
394 SES_OBJSTAT_CRIT;
395 /*
396 * FAIL and FAN STOPPED synthesized
397 */
398 cache->elm_map[oid].encstat[3] |= 0x10;
399 cache->elm_map[oid].encstat[3] &= ~0x07;
400 /*
401 * Enclosure marked with CRITICAL error
402 * if only one fan or no thermometers,
403 * else the NONCRITICAL error is set.
404 */
405 if (cfg->Nfans == 1 || (cfg->Ntherm + cfg->Ntstats) == 0)
406 cfg->enc_status |= SES_ENCSTAT_CRITICAL;
407 else
408 cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
409 break;
410 case 2:
411 cache->elm_map[oid].encstat[0] =
412 SES_OBJSTAT_NOTINSTALLED;
413 cache->elm_map[oid].encstat[3] |= 0x10;
414 cache->elm_map[oid].encstat[3] &= ~0x07;
415 /*
416 * Enclosure marked with CRITICAL error
417 * if only one fan or no thermometers,
418 * else the NONCRITICAL error is set.
419 */
420 if (cfg->Nfans == 1)
421 cfg->enc_status |= SES_ENCSTAT_CRITICAL;
422 else
423 cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
424 break;
425 case 0x80:
426 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
427 cache->elm_map[oid].encstat[3] = 0;
428 cfg->enc_status |= SES_ENCSTAT_INFO;
429 break;
430 default:
431 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
432 ENC_VLOG(enc, "Unknown fan%d status 0x%x\n", i,
433 buf[r] & 0xff);
434 break;
435 }
436 cache->elm_map[oid++].svalid = 1;
437 r++;
438 }
439
440 /*
441 * No matter how you cut it, no cooling elements when there
442 * should be some there is critical.
443 */
444 if (cfg->Nfans && nitems == 0)
445 cfg->enc_status |= SES_ENCSTAT_CRITICAL;
446
447 for (i = 0; i < cfg->Npwr; i++) {
448 SAFT_BAIL(r, xfer_len);
449 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
450 cache->elm_map[oid].encstat[1] = 0; /* resvd */
451 cache->elm_map[oid].encstat[2] = 0; /* resvd */
452 cache->elm_map[oid].encstat[3] = 0x20; /* requested on */
453 switch (buf[r]) {
454 case 0x00: /* pws operational and on */
455 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
456 break;
457 case 0x01: /* pws operational and off */
458 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
459 cache->elm_map[oid].encstat[3] = 0x10;
460 cfg->enc_status |= SES_ENCSTAT_INFO;
461 break;
462 case 0x10: /* pws is malfunctioning and commanded on */
463 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
464 cache->elm_map[oid].encstat[3] = 0x61;
465 cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
466 break;
467
468 case 0x11: /* pws is malfunctioning and commanded off */
469 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
470 cache->elm_map[oid].encstat[3] = 0x51;
471 cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
472 break;
473 case 0x20: /* pws is not present */
474 cache->elm_map[oid].encstat[0] =
475 SES_OBJSTAT_NOTINSTALLED;
476 cache->elm_map[oid].encstat[3] = 0;
477 cfg->enc_status |= SES_ENCSTAT_INFO;
478 break;
479 case 0x21: /* pws is present */
480 /*
481 * This is for enclosures that cannot tell whether the
482 * device is on or malfunctioning, but know that it is
483 * present. Just fall through.
484 */
485 /* FALLTHROUGH */
486 case 0x80: /* Unknown or Not Reportable Status */
487 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
488 cache->elm_map[oid].encstat[3] = 0;
489 cfg->enc_status |= SES_ENCSTAT_INFO;
490 break;
491 default:
492 ENC_VLOG(enc, "unknown power supply %d status (0x%x)\n",
493 i, buf[r] & 0xff);
494 break;
495 }
496 enc->enc_cache.elm_map[oid++].svalid = 1;
497 r++;
498 }
499
500 /*
501 * Copy Slot SCSI IDs
502 */
503 for (i = 0; i < cfg->Nslots; i++) {
504 SAFT_BAIL(r, xfer_len);
505 if (cache->elm_map[cfg->slotoff + i].elm_type == ELMTYP_DEVICE)
506 cache->elm_map[cfg->slotoff + i].encstat[1] = buf[r];
507 r++;
508 }
509
510 /*
511 * We always have doorlock status, no matter what,
512 * but we only save the status if we have one.
513 */
514 SAFT_BAIL(r, xfer_len);
515 if (cfg->DoorLock) {
516 /*
517 * 0 = Door Locked
518 * 1 = Door Unlocked, or no Lock Installed
519 * 0x80 = Unknown or Not Reportable Status
520 */
521 cache->elm_map[oid].encstat[1] = 0;
522 cache->elm_map[oid].encstat[2] = 0;
523 switch (buf[r]) {
524 case 0:
525 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
526 cache->elm_map[oid].encstat[3] = 0;
527 break;
528 case 1:
529 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
530 cache->elm_map[oid].encstat[3] = 1;
531 break;
532 case 0x80:
533 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
534 cache->elm_map[oid].encstat[3] = 0;
535 cfg->enc_status |= SES_ENCSTAT_INFO;
536 break;
537 default:
538 cache->elm_map[oid].encstat[0] =
539 SES_OBJSTAT_UNSUPPORTED;
540 ENC_VLOG(enc, "unknown lock status 0x%x\n",
541 buf[r] & 0xff);
542 break;
543 }
544 cache->elm_map[oid++].svalid = 1;
545 }
546 r++;
547
548 /*
549 * We always have speaker status, no matter what,
550 * but we only save the status if we have one.
551 */
552 SAFT_BAIL(r, xfer_len);
553 if (cfg->Nspkrs) {
554 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
555 cache->elm_map[oid].encstat[1] = 0;
556 cache->elm_map[oid].encstat[2] = 0;
557 if (buf[r] == 0) {
558 cache->elm_map[oid].encstat[0] |= SESCTL_DISABLE;
559 cache->elm_map[oid].encstat[3] |= 0x40;
560 }
561 cache->elm_map[oid++].svalid = 1;
562 }
563 r++;
564
565 /*
566 * Now, for "pseudo" thermometers, we have two bytes
567 * of information in enclosure status- 16 bits. Actually,
568 * the MSB is a single TEMP ALERT flag indicating whether
569 * any other bits are set, but, thanks to fuzzy thinking,
570 * in the SAF-TE spec, this can also be set even if no
571 * other bits are set, thus making this really another
572 * binary temperature sensor.
573 */
574
575 SAFT_BAIL(r + cfg->Ntherm, xfer_len);
576 tempflags = buf[r + cfg->Ntherm];
577 SAFT_BAIL(r + cfg->Ntherm + 1, xfer_len);
578 tempflags |= (tempflags << 8) | buf[r + cfg->Ntherm + 1];
579
580 for (i = 0; i < cfg->Ntherm; i++) {
581 SAFT_BAIL(r, xfer_len);
582 /*
583 * Status is a range from -10 to 245 deg Celsius,
584 * which we need to normalize to -20 to -245 according
585 * to the latest SCSI spec, which makes little
586 * sense since this would overflow an 8bit value.
587 * Well, still, the base normalization is -20,
588 * not -10, so we have to adjust.
589 *
590 * So what's over and under temperature?
591 * Hmm- we'll state that 'normal' operating
592 * is 10 to 40 deg Celsius.
593 */
594
595 /*
596 * Actually.... All of the units that people out in the world
597 * seem to have do not come even close to setting a value that
598 * complies with this spec.
599 *
600 * The closest explanation I could find was in an
601 * LSI-Logic manual, which seemed to indicate that
602 * this value would be set by whatever the I2C code
603 * would interpolate from the output of an LM75
604 * temperature sensor.
605 *
606 * This means that it is impossible to use the actual
607 * numeric value to predict anything. But we don't want
608 * to lose the value. So, we'll propagate the *uncorrected*
609 * value and set SES_OBJSTAT_NOTAVAIL. We'll depend on the
610 * temperature flags for warnings.
611 */
612 if (tempflags & (1 << i)) {
613 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
614 cfg->enc_status |= SES_ENCSTAT_CRITICAL;
615 } else
616 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
617 cache->elm_map[oid].encstat[1] = 0;
618 cache->elm_map[oid].encstat[2] = buf[r];
619 cache->elm_map[oid].encstat[3] = 0;
620 cache->elm_map[oid++].svalid = 1;
621 r++;
622 }
623
624 for (i = 0; i <= cfg->Ntstats; i++) {
625 cache->elm_map[oid].encstat[1] = 0;
626 if (tempflags & (1 <<
627 ((i == cfg->Ntstats) ? 15 : (cfg->Ntherm + i)))) {
628 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
629 cache->elm_map[4].encstat[2] = 0xff;
630 /*
631 * Set 'over temperature' failure.
632 */
633 cache->elm_map[oid].encstat[3] = 8;
634 cfg->enc_status |= SES_ENCSTAT_CRITICAL;
635 } else {
636 /*
637 * We used to say 'not available' and synthesize a
638 * nominal 30 deg (C)- that was wrong. Actually,
639 * Just say 'OK', and use the reserved value of
640 * zero.
641 */
642 if ((cfg->Ntherm + cfg->Ntstats) == 0)
643 cache->elm_map[oid].encstat[0] =
644 SES_OBJSTAT_NOTAVAIL;
645 else
646 cache->elm_map[oid].encstat[0] =
647 SES_OBJSTAT_OK;
648 cache->elm_map[oid].encstat[2] = 0;
649 cache->elm_map[oid].encstat[3] = 0;
650 }
651 cache->elm_map[oid++].svalid = 1;
652 }
653 r += 2;
654
655 cache->enc_status =
656 cfg->enc_status | cfg->slot_status | cfg->adm_status;
657 return (0);
658 }
659
660 static int
safte_process_slotstatus(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t ** bufp,int error,int xfer_len)661 safte_process_slotstatus(enc_softc_t *enc, struct enc_fsm_state *state,
662 union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
663 {
664 struct scfg *cfg;
665 uint8_t *buf = *bufp;
666 enc_cache_t *cache = &enc->enc_cache;
667 int oid, r, i;
668
669 cfg = enc->enc_private;
670 if (cfg == NULL)
671 return (ENXIO);
672 if (error != 0)
673 return (error);
674 cfg->slot_status = 0;
675 oid = cfg->slotoff;
676 for (r = i = 0; i < cfg->Nslots; i++, r += 4) {
677 SAFT_BAIL(r+3, xfer_len);
678 if (cache->elm_map[oid].elm_type == ELMTYP_ARRAY_DEV)
679 cache->elm_map[oid].encstat[1] = 0;
680 cache->elm_map[oid].encstat[2] &= SESCTL_RQSID;
681 cache->elm_map[oid].encstat[3] = 0;
682 if ((buf[r+3] & 0x01) == 0) { /* no device */
683 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NOTINSTALLED;
684 } else if (buf[r+0] & 0x02) {
685 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
686 cfg->slot_status |= SES_ENCSTAT_CRITICAL;
687 } else if (buf[r+0] & 0x40) {
688 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
689 cfg->slot_status |= SES_ENCSTAT_NONCRITICAL;
690 } else {
691 cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
692 }
693 if (buf[r+3] & 0x2) {
694 if (buf[r+3] & 0x01)
695 cache->elm_map[oid].encstat[2] |= SESCTL_RQSRMV;
696 else
697 cache->elm_map[oid].encstat[2] |= SESCTL_RQSINS;
698 }
699 if ((buf[r+3] & 0x04) == 0)
700 cache->elm_map[oid].encstat[3] |= SESCTL_DEVOFF;
701 if (buf[r+0] & 0x02)
702 cache->elm_map[oid].encstat[3] |= SESCTL_RQSFLT;
703 if (buf[r+0] & 0x40)
704 cache->elm_map[oid].encstat[0] |= SESCTL_PRDFAIL;
705 if (cache->elm_map[oid].elm_type == ELMTYP_ARRAY_DEV) {
706 if (buf[r+0] & 0x01)
707 cache->elm_map[oid].encstat[1] |= 0x80;
708 if (buf[r+0] & 0x04)
709 cache->elm_map[oid].encstat[1] |= 0x02;
710 if (buf[r+0] & 0x08)
711 cache->elm_map[oid].encstat[1] |= 0x04;
712 if (buf[r+0] & 0x10)
713 cache->elm_map[oid].encstat[1] |= 0x08;
714 if (buf[r+0] & 0x20)
715 cache->elm_map[oid].encstat[1] |= 0x10;
716 if (buf[r+1] & 0x01)
717 cache->elm_map[oid].encstat[1] |= 0x20;
718 if (buf[r+1] & 0x02)
719 cache->elm_map[oid].encstat[1] |= 0x01;
720 }
721 cache->elm_map[oid++].svalid = 1;
722 }
723
724 cache->enc_status =
725 cfg->enc_status | cfg->slot_status | cfg->adm_status;
726 return (0);
727 }
728
729 static int
safte_fill_control_request(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t * buf)730 safte_fill_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
731 union ccb *ccb, uint8_t *buf)
732 {
733 struct scfg *cfg;
734 enc_element_t *ep, *ep1;
735 safte_control_request_t *req;
736 int i, idx, xfer_len;
737
738 cfg = enc->enc_private;
739 if (cfg == NULL)
740 return (ENXIO);
741
742 if (enc->enc_cache.nelms == 0) {
743 enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
744 return (-1);
745 }
746
747 if (cfg->current_request == NULL) {
748 cfg->current_request = TAILQ_FIRST(&cfg->requests);
749 TAILQ_REMOVE(&cfg->requests, cfg->current_request, links);
750 cfg->current_request_stage = 0;
751 cfg->current_request_stages = 1;
752 }
753 req = cfg->current_request;
754
755 idx = (int)req->elm_idx;
756 if (req->elm_idx == SES_SETSTATUS_ENC_IDX) {
757 cfg->adm_status = req->elm_stat[0] & ALL_ENC_STAT;
758 cfg->flag1 &= ~(SAFT_FLG1_GLOBFAIL|SAFT_FLG1_GLOBWARN);
759 if (req->elm_stat[0] & (SES_ENCSTAT_CRITICAL|SES_ENCSTAT_UNRECOV))
760 cfg->flag1 |= SAFT_FLG1_GLOBFAIL;
761 else if (req->elm_stat[0] & SES_ENCSTAT_NONCRITICAL)
762 cfg->flag1 |= SAFT_FLG1_GLOBWARN;
763 buf[0] = SAFTE_WT_GLOBAL;
764 buf[1] = cfg->flag1;
765 buf[2] = cfg->flag2;
766 buf[3] = 0;
767 xfer_len = 16;
768 } else {
769 ep = &enc->enc_cache.elm_map[idx];
770
771 switch (ep->elm_type) {
772 case ELMTYP_DEVICE:
773 case ELMTYP_ARRAY_DEV:
774 switch (cfg->current_request_stage) {
775 case 0:
776 ep->priv = 0;
777 if (req->elm_stat[0] & SESCTL_PRDFAIL)
778 ep->priv |= 0x40;
779 if (req->elm_stat[3] & SESCTL_RQSFLT)
780 ep->priv |= 0x02;
781 if (ep->elm_type == ELMTYP_ARRAY_DEV) {
782 if (req->elm_stat[1] & 0x01)
783 ep->priv |= 0x200;
784 if (req->elm_stat[1] & 0x02)
785 ep->priv |= 0x04;
786 if (req->elm_stat[1] & 0x04)
787 ep->priv |= 0x08;
788 if (req->elm_stat[1] & 0x08)
789 ep->priv |= 0x10;
790 if (req->elm_stat[1] & 0x10)
791 ep->priv |= 0x20;
792 if (req->elm_stat[1] & 0x20)
793 ep->priv |= 0x100;
794 if (req->elm_stat[1] & 0x80)
795 ep->priv |= 0x01;
796 }
797 if (ep->priv == 0)
798 ep->priv |= 0x01; /* no errors */
799
800 buf[0] = SAFTE_WT_DSTAT;
801 for (i = 0; i < cfg->Nslots; i++) {
802 ep1 = &enc->enc_cache.elm_map[cfg->slotoff + i];
803 buf[1 + (3 * i)] = ep1->priv;
804 buf[2 + (3 * i)] = ep1->priv >> 8;
805 }
806 xfer_len = cfg->Nslots * 3 + 1;
807 #define DEVON(x) (!(((x)[2] & SESCTL_RQSINS) | \
808 ((x)[2] & SESCTL_RQSRMV) | \
809 ((x)[3] & SESCTL_DEVOFF)))
810 if (DEVON(req->elm_stat) != DEVON(ep->encstat))
811 cfg->current_request_stages++;
812 #define IDON(x) (!!((x)[2] & SESCTL_RQSID))
813 if (IDON(req->elm_stat) != IDON(ep->encstat))
814 cfg->current_request_stages++;
815 break;
816 case 1:
817 case 2:
818 buf[0] = SAFTE_WT_SLTOP;
819 buf[1] = idx - cfg->slotoff;
820 if (cfg->current_request_stage == 1 &&
821 DEVON(req->elm_stat) != DEVON(ep->encstat)) {
822 if (DEVON(req->elm_stat))
823 buf[2] = 0x01;
824 else
825 buf[2] = 0x02;
826 } else {
827 if (IDON(req->elm_stat))
828 buf[2] = 0x04;
829 else
830 buf[2] = 0x00;
831 ep->encstat[2] &= ~SESCTL_RQSID;
832 ep->encstat[2] |= req->elm_stat[2] &
833 SESCTL_RQSID;
834 }
835 xfer_len = 64;
836 break;
837 default:
838 return (EINVAL);
839 }
840 break;
841 case ELMTYP_POWER:
842 cfg->current_request_stages = 2;
843 switch (cfg->current_request_stage) {
844 case 0:
845 if (req->elm_stat[3] & SESCTL_RQSTFAIL) {
846 cfg->flag1 |= SAFT_FLG1_ENCPWRFAIL;
847 } else {
848 cfg->flag1 &= ~SAFT_FLG1_ENCPWRFAIL;
849 }
850 buf[0] = SAFTE_WT_GLOBAL;
851 buf[1] = cfg->flag1;
852 buf[2] = cfg->flag2;
853 buf[3] = 0;
854 xfer_len = 16;
855 break;
856 case 1:
857 buf[0] = SAFTE_WT_ACTPWS;
858 buf[1] = idx - cfg->pwroff;
859 if (req->elm_stat[3] & SESCTL_RQSTON)
860 buf[2] = 0x01;
861 else
862 buf[2] = 0x00;
863 buf[3] = 0;
864 xfer_len = 16;
865 default:
866 return (EINVAL);
867 }
868 break;
869 case ELMTYP_FAN:
870 if ((req->elm_stat[3] & 0x7) != 0)
871 cfg->current_request_stages = 2;
872 switch (cfg->current_request_stage) {
873 case 0:
874 if (req->elm_stat[3] & SESCTL_RQSTFAIL)
875 cfg->flag1 |= SAFT_FLG1_ENCFANFAIL;
876 else
877 cfg->flag1 &= ~SAFT_FLG1_ENCFANFAIL;
878 buf[0] = SAFTE_WT_GLOBAL;
879 buf[1] = cfg->flag1;
880 buf[2] = cfg->flag2;
881 buf[3] = 0;
882 xfer_len = 16;
883 break;
884 case 1:
885 buf[0] = SAFTE_WT_FANSPD;
886 buf[1] = idx;
887 if (req->elm_stat[3] & SESCTL_RQSTON) {
888 if ((req->elm_stat[3] & 0x7) == 7)
889 buf[2] = 4;
890 else if ((req->elm_stat[3] & 0x7) >= 5)
891 buf[2] = 3;
892 else if ((req->elm_stat[3] & 0x7) >= 3)
893 buf[2] = 2;
894 else
895 buf[2] = 1;
896 } else
897 buf[2] = 0;
898 buf[3] = 0;
899 xfer_len = 16;
900 ep->encstat[3] = req->elm_stat[3] & 0x67;
901 default:
902 return (EINVAL);
903 }
904 break;
905 case ELMTYP_DOORLOCK:
906 if (req->elm_stat[3] & 0x1)
907 cfg->flag2 &= ~SAFT_FLG2_LOCKDOOR;
908 else
909 cfg->flag2 |= SAFT_FLG2_LOCKDOOR;
910 buf[0] = SAFTE_WT_GLOBAL;
911 buf[1] = cfg->flag1;
912 buf[2] = cfg->flag2;
913 buf[3] = 0;
914 xfer_len = 16;
915 break;
916 case ELMTYP_ALARM:
917 if ((req->elm_stat[0] & SESCTL_DISABLE) ||
918 (req->elm_stat[3] & 0x40)) {
919 cfg->flag2 &= ~SAFT_FLG1_ALARM;
920 } else if ((req->elm_stat[3] & 0x0f) != 0) {
921 cfg->flag2 |= SAFT_FLG1_ALARM;
922 } else {
923 cfg->flag2 &= ~SAFT_FLG1_ALARM;
924 }
925 buf[0] = SAFTE_WT_GLOBAL;
926 buf[1] = cfg->flag1;
927 buf[2] = cfg->flag2;
928 buf[3] = 0;
929 xfer_len = 16;
930 ep->encstat[3] = req->elm_stat[3];
931 break;
932 default:
933 return (EINVAL);
934 }
935 }
936
937 if (enc->enc_type == ENC_SEMB_SAFT) {
938 semb_write_buffer(&ccb->ataio, /*retries*/5,
939 NULL, MSG_SIMPLE_Q_TAG,
940 buf, xfer_len, state->timeout);
941 } else {
942 scsi_write_buffer(&ccb->csio, /*retries*/5,
943 NULL, MSG_SIMPLE_Q_TAG, 1,
944 0, 0, buf, xfer_len,
945 SSD_FULL_SIZE, state->timeout);
946 }
947 return (0);
948 }
949
950 static int
safte_process_control_request(enc_softc_t * enc,struct enc_fsm_state * state,union ccb * ccb,uint8_t ** bufp,int error,int xfer_len)951 safte_process_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
952 union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
953 {
954 struct scfg *cfg;
955 safte_control_request_t *req;
956 int idx, type;
957
958 cfg = enc->enc_private;
959 if (cfg == NULL)
960 return (ENXIO);
961
962 req = cfg->current_request;
963 if (req->result == 0)
964 req->result = error;
965 if (++cfg->current_request_stage >= cfg->current_request_stages) {
966 idx = req->elm_idx;
967 if (idx == SES_SETSTATUS_ENC_IDX)
968 type = -1;
969 else
970 type = enc->enc_cache.elm_map[idx].elm_type;
971 if (type == ELMTYP_DEVICE || type == ELMTYP_ARRAY_DEV)
972 enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
973 else
974 enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
975 cfg->current_request = NULL;
976 wakeup(req);
977 } else {
978 enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
979 }
980 return (0);
981 }
982
983 static void
safte_softc_invalidate(enc_softc_t * enc)984 safte_softc_invalidate(enc_softc_t *enc)
985 {
986 struct scfg *cfg;
987
988 cfg = enc->enc_private;
989 safte_terminate_control_requests(&cfg->requests, ENXIO);
990 }
991
992 static void
safte_softc_cleanup(enc_softc_t * enc)993 safte_softc_cleanup(enc_softc_t *enc)
994 {
995
996 ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
997 ENC_FREE_AND_NULL(enc->enc_private);
998 enc->enc_cache.nelms = 0;
999 }
1000
1001 static int
safte_init_enc(enc_softc_t * enc)1002 safte_init_enc(enc_softc_t *enc)
1003 {
1004 struct scfg *cfg;
1005 int err;
1006 static char cdb0[6] = { SEND_DIAGNOSTIC };
1007
1008 cfg = enc->enc_private;
1009 if (cfg == NULL)
1010 return (ENXIO);
1011
1012 err = enc_runcmd(enc, cdb0, 6, NULL, 0);
1013 if (err) {
1014 return (err);
1015 }
1016 DELAY(5000);
1017 cfg->flag1 = 0;
1018 cfg->flag2 = 0;
1019 err = safte_set_enc_status(enc, 0, 1);
1020 return (err);
1021 }
1022
1023 static int
safte_set_enc_status(enc_softc_t * enc,uint8_t encstat,int slpflag)1024 safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag)
1025 {
1026 struct scfg *cfg;
1027 safte_control_request_t req;
1028
1029 cfg = enc->enc_private;
1030 if (cfg == NULL)
1031 return (ENXIO);
1032
1033 req.elm_idx = SES_SETSTATUS_ENC_IDX;
1034 req.elm_stat[0] = encstat & 0xf;
1035 req.result = 0;
1036
1037 TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
1038 enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
1039 cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
1040
1041 return (req.result);
1042 }
1043
1044 static int
safte_get_elm_status(enc_softc_t * enc,encioc_elm_status_t * elms,int slpflg)1045 safte_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflg)
1046 {
1047 int i = (int)elms->elm_idx;
1048
1049 elms->cstat[0] = enc->enc_cache.elm_map[i].encstat[0];
1050 elms->cstat[1] = enc->enc_cache.elm_map[i].encstat[1];
1051 elms->cstat[2] = enc->enc_cache.elm_map[i].encstat[2];
1052 elms->cstat[3] = enc->enc_cache.elm_map[i].encstat[3];
1053 return (0);
1054 }
1055
1056 static int
safte_set_elm_status(enc_softc_t * enc,encioc_elm_status_t * elms,int slpflag)1057 safte_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
1058 {
1059 struct scfg *cfg;
1060 safte_control_request_t req;
1061
1062 cfg = enc->enc_private;
1063 if (cfg == NULL)
1064 return (ENXIO);
1065
1066 /* If this is clear, we don't do diddly. */
1067 if ((elms->cstat[0] & SESCTL_CSEL) == 0)
1068 return (0);
1069
1070 req.elm_idx = elms->elm_idx;
1071 memcpy(&req.elm_stat, elms->cstat, sizeof(req.elm_stat));
1072 req.result = 0;
1073
1074 TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
1075 enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
1076 cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
1077
1078 return (req.result);
1079 }
1080
1081 static void
safte_poll_status(enc_softc_t * enc)1082 safte_poll_status(enc_softc_t *enc)
1083 {
1084
1085 enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
1086 enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
1087 }
1088
1089 static struct enc_vec safte_enc_vec =
1090 {
1091 .softc_invalidate = safte_softc_invalidate,
1092 .softc_cleanup = safte_softc_cleanup,
1093 .init_enc = safte_init_enc,
1094 .set_enc_status = safte_set_enc_status,
1095 .get_elm_status = safte_get_elm_status,
1096 .set_elm_status = safte_set_elm_status,
1097 .poll_status = safte_poll_status
1098 };
1099
1100 int
safte_softc_init(enc_softc_t * enc)1101 safte_softc_init(enc_softc_t *enc)
1102 {
1103 struct scfg *cfg;
1104
1105 enc->enc_vec = safte_enc_vec;
1106 enc->enc_fsm_states = enc_fsm_states;
1107
1108 if (enc->enc_private == NULL) {
1109 enc->enc_private = ENC_MALLOCZ(SAFT_PRIVATE);
1110 if (enc->enc_private == NULL)
1111 return (ENOMEM);
1112 }
1113 cfg = enc->enc_private;
1114
1115 enc->enc_cache.nelms = 0;
1116 enc->enc_cache.enc_status = 0;
1117
1118 TAILQ_INIT(&cfg->requests);
1119 return (0);
1120 }
1121