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