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