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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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