43#include <sys/kernel.h>
45#include <sys/malloc.h>
103 union ses_fcobj_hdr *
fc;
134 while ((req = TAILQ_FIRST(reqlist)) != NULL) {
135 TAILQ_REMOVE(reqlist, req, links);
271 {
"SES_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
282 "SES_UPDATE_GETCONFIG",
291 "SES_UPDATE_GETSTATUS",
300 "SES_UPDATE_GETELMDESCS",
309 "SES_UPDATE_GETELMADDLSTATUS",
318 "SES_PROCESS_CONTROL_REQS",
327 "SES_PUBLISH_PHYSPATHS",
369#define SES_FLAG_TIMEDCOMP 0x01
370#define SES_FLAG_ADDLSTATUS 0x02
371#define SES_FLAG_DESC 0x04
378SYSCTL_INT(_kern_cam_enc, OID_AUTO, search_globally, CTLFLAG_RWTUN,
456 (
"Corrupted element iterator. %d not less than %d",
529 if (*cur_index == element_index) {
536 && *cur_index != element_index)
539 if (*cur_index != element_index)
567 ENC_DLOG(enc,
"%s: enter\n", __func__);
574 cur_elm != last_elm; cur_elm++) {
580 bzero(&elmpriv->
addl,
sizeof(elmpriv->
addl));
598 ENC_DLOG(enc,
"%s: enter\n", __func__);
605 cur_elm != last_elm; cur_elm++) {
610 elmpriv->
descr = NULL;
626 ENC_DLOG(enc,
"%s: enter\n", __func__);
643 ENC_DLOG(enc,
"%s: enter\n", __func__);
651 cur_elm != last_elm; cur_elm++) {
656 ENC_DLOG(enc,
"%s: exit\n", __func__);
665 ENC_DLOG(enc,
"%s: enter\n", __func__);
686 ENC_DLOG(enc,
"%s: exit\n", __func__);
707 *dst_ses_cache = *src_ses_cache;
720 M_SCSIENC, M_WAITOK);
724 src_elm != last_elm; src_elm++, dst_elm++) {
726 M_SCSIENC, M_WAITOK);
737 return ((obj)->base_hdr.byte1 >> 6);
742 return ((hdr)->byte0 & 0xf);
747 return ((hdr)->byte0 >> 4 & 0x1);
752 return ((hdr)->byte0 >> 7);
757 return ((hdr)->type0_noneip.byte1 & 0x1);
762 return ((phy)->target_ports & 0x1);
767 return ((phy)->target_ports >> 7);
772 return (((phy)->byte0 >> 4) & 0x7);
797 return (cache_gc == cur_gc);
824 size_t devid_record_size;
827 addl = &(elmpriv->
addl);
832 uint8_t devid_buf[devid_record_size];
847 callback(enc, elm, devid, callback_arg);
902 memset(&cdm, 0,
sizeof(cdm));
922 cdm.num_matches == 0)
957 addl = &(elmpriv->
addl);
959 if (addl->
hdr == NULL)
985 memset(&cgd, 0,
sizeof(cgd));
990 callback(enc, elm, path, callback_arg);
1014 sb = (
struct sbuf *)arg;
1045 old_physpath = malloc(MAXPATHLEN, M_SCSIENC, M_WAITOK|M_ZERO);
1047 memset(&cdai, 0,
sizeof(cdai));
1052 cdai.
bufsiz = MAXPATHLEN;
1053 cdai.
buf = old_physpath;
1058 if (strcmp(old_physpath, sbuf_data(args->physpath)) != 0) {
1063 cdai.
bufsiz = sbuf_len(args->physpath);
1064 cdai.
buf = sbuf_data(args->physpath);
1072 free(old_physpath, M_SCSIENC);
1101 if (elmpriv->
addl.
hdr == NULL)
1108 memset(&cdai, 0,
sizeof(cdai));
1114 cdai.
buf = devid = malloc(cdai.
bufsiz, M_SCSIENC, M_WAITOK|M_ZERO);
1128 if (sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND) == NULL) {
1133 sbuf_printf(&sb,
"id1,enc@n%jx/type@%x/slot@%x",
1138 sbuf_cat(&sb,
"/elmdesc@");
1139 for (i = 0, c = elmpriv->
descr; i < elmpriv->descr_len;
1141 if (!isprint(*c) || isspace(*c) || *c ==
'/')
1142 sbuf_putc(&sb,
'_');
1159 ret = args.num_set == 0 ? ENOENT : 0;
1188 cdb[3] = bufsiz >> 8;
1189 cdb[4] = bufsiz & 0xff;
1210 size_t mode_buf_len;
1219 if (mode_buf == NULL)
1233 ENC_VLOG(enc,
"Timed Completion Unsupported\n");
1246 mgmt->
byte5 &= ~SES_MGMT_TIMED_COMP_EN;
1251 FALSE, TRUE, mode_buf, mode_buf_len,
1256 ENC_VLOG(enc,
"Timed Completion Set Failed\n");
1262 ENC_LOG(enc,
"Timed Completion Enabled\n");
1265 ENC_LOG(enc,
"Timed Completion Disabled\n");
1286 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1293 (
"entering %s(%p, %d)\n", __func__, bufp, xfer_len));
1301 if (xfer_len <
sizeof(*page)) {
1302 ENC_VLOG(enc,
"Unable to parse Diag Pages List Header\n");
1309 ENC_VLOG(enc,
"Diag Pages List Too Long\n");
1312 ENC_DLOG(enc,
"%s: page length %d, xfer_len %d\n",
1313 __func__,
length, xfer_len);
1316 for (i = 0; i <
length; i++) {
1324 ENC_DLOG(enc,
"%s: exiting with err %d\n", __func__, err);
1339 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1358 uint8_t *last_valid_byte;
1360 const char *type_text;
1363 (
"entering %s(%p, %d)\n", __func__, bufp, xfer_len));
1373 if (xfer_len <
sizeof(cfg_page->
hdr)) {
1374 ENC_VLOG(enc,
"Unable to parse SES Config Header\n");
1381 if (length > xfer_len) {
1382 ENC_VLOG(enc,
"Enclosure Config Page Too Long\n");
1385 last_valid_byte = &buf[length - 1];
1387 ENC_DLOG(enc,
"%s: total page length %d, xfer_len %d\n",
1388 __func__, length, xfer_len);
1398 ENC_VLOG(enc,
"Generation Code 0x%x has %d SubEnclosures\n",
1411 *
sizeof(*
subencs), M_SCSIENC, M_WAITOK|M_ZERO);
1422 buf_subenc = cfg_page->
subencs;
1426 while (cur_subenc <= last_subenc) {
1428 ENC_VLOG(enc,
"Enclosure %d Beyond End of "
1429 "Descriptors\n", cur_subenc -
subencs);
1434 ENC_VLOG(enc,
" SubEnclosure ID %d, %d Types With this ID, "
1435 "Descriptor Length %d, offset %d\n", buf_subenc->
subenc_id,
1437 &buf_subenc->
byte0 - buf);
1442 *cur_subenc = buf_subenc;
1448 ses_types = malloc(ntype *
sizeof(*ses_types),
1449 M_SCSIENC, M_WAITOK|M_ZERO);
1458 (&(*last_subenc)->length + (*last_subenc)->length + 1);
1459 last_buf_type = cur_buf_type + ntype - 1;
1460 type_text = (
const uint8_t *)(last_buf_type + 1);
1462 sestype = ses_types;
1463 while (cur_buf_type <= last_buf_type) {
1465 ENC_VLOG(enc,
"Runt Enclosure Type Header %d\n",
1466 sestype - ses_types);
1470 sestype->
hdr = cur_buf_type;
1471 sestype->
text = type_text;
1473 ENC_VLOG(enc,
" Type Desc[%d]: Type 0x%x, MaxElt %d, In Subenc "
1474 "%d, Text Length %d: %.*s\n", sestype - ses_types,
1487 M_SCSIENC, M_WAITOK|M_ZERO);
1494 ENC_DLOG(enc,
"%s: checking obj %d(%d,%d)\n", __func__,
1503 M_SCSIENC, M_WAITOK|M_ZERO);
1504 ENC_DLOG(enc,
"%s: creating elmpriv %d(%d,%d) subenc %d "
1519 ENC_DLOG(enc,
"%s: exiting with err %d\n", __func__, err);
1534 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1553 ENC_DLOG(enc,
"%s: enter (%p, %p, %d)\n", __func__, enc, buf, xfer_len);
1568 if (length > xfer_len) {
1569 ENC_VLOG(enc,
"Enclosure Status Page Too Long\n");
1575 ENC_DLOG(enc,
"Got Short Enclosure Status page\n");
1585 if (length < (
sizeof(*page) +
sizeof(*page->
elements))) {
1586 ENC_VLOG(enc,
"Enclosure Status Page Too Short\n");
1591 ENC_DLOG(enc,
"%s: Generation count change detected\n",
1611 &buf[length -
sizeof(*last_stat)];
1612 ENC_DLOG(enc,
"%s: total page length %d, xfer_len %d\n",
1613 __func__, length, xfer_len);
1614 while (cur_stat <= last_stat
1616 ENC_DLOG(enc,
"%s: obj %d(%d,%d) off=0x%tx status=%jx\n",
1621 memcpy(&element->encstat, cur_stat,
sizeof(element->encstat));
1622 element->svalid = 1;
1627 ENC_VLOG(enc,
"Status page, length insufficient for "
1628 "expected number of objects\n");
1630 if (cur_stat <= last_stat)
1631 ENC_VLOG(enc,
"Status page, exhausted objects before "
1632 "exhausing page\n");
1637 ENC_DLOG(enc,
"%s: exiting with error %d\n", __func__, err);
1703 int,
int,
int,
int);
1705 int,
int,
int,
int);
1719 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1755 ENC_DLOG(enc,
"Additional Element Status Page Length 0x%x\n", length);
1758 ENC_VLOG(enc,
"Runt Additional Element Status Page\n");
1761 if (length > xfer_len) {
1762 ENC_VLOG(enc,
"Additional Element Status Page Too Long\n");
1767 ENC_DLOG(enc,
"%s: Generation count change detected\n",
1796 int expected_index, index;
1808 ENC_VLOG(enc,
"%s: provided %selement index "
1809 "%d is lower then expected %d\n",
1811 eip_hdr->
byte2) ?
"global " :
"",
1818 if (telement == NULL) {
1819 ENC_VLOG(enc,
"%s: provided %selement index "
1820 "%d does not exist\n", __func__,
1827 ENC_VLOG(enc,
"%s: provided %selement index "
1828 "%d can't have additional status\n",
1850 if (index > expected_index
1852 ENC_VLOG(enc,
"%s: provided %s element"
1853 "index %d skips mandatory status "
1854 " element at index %d\n",
1856 eip_hdr->
byte2) ?
"global " :
"",
1857 index, expected_index);
1861 ENC_DLOG(enc,
"%s: global element index=%d, type index=%d "
1862 "type element index=%d, offset=0x%x, "
1863 "byte0=0x%x, length=0x%x\n", __func__,
1873 ENC_VLOG(enc,
"Element %d Beyond End "
1874 "of Additional Element Status Descriptors\n",
1881 offset += elm_hdr->
length;
1888 proto_info_len = elm_hdr->
length
1894 if (elm_hdr->
length == 0)
1897 &buf[offset], proto_info_len);
1900 if (elm_hdr->
length <= 2)
1916 ENC_VLOG(enc,
"Element %d: Unknown Additional Element "
1922 offset += proto_info_len;
1935 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1952 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
1977 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
2003 const char *invalid =
"<invalid>";
2006 for (i = 0; i < *len; i++) {
2009 }
else if (desc[i] < 0x20 || desc[i] > 0x7e) {
2010 *len = strlen(invalid);
2028 union ccb *
ccb, uint8_t **bufp,
int error,
int xfer_len)
2035 u_long length, plength;
2060 ENC_VLOG(enc,
"Runt Element Descriptor Page\n");
2063 if (plength > xfer_len) {
2064 ENC_VLOG(enc,
"Element Descriptor Page Too Long\n");
2069 ENC_VLOG(enc,
"%s: Generation count change detected\n",
2078 while (offset < plength
2081 ENC_VLOG(enc,
"Element %d Descriptor Header Past "
2087 ENC_DLOG(enc,
"%s: obj %d(%d,%d) length=%d off=%d\n", __func__,
2090 if ((offset +
sizeof(*hdr) +
length) > plength) {
2091 ENC_VLOG(enc,
"Element%d Descriptor Past "
2095 offset +=
sizeof(*hdr);
2098 elmpriv = element->elm_private;
2120 union ccb *
ccb, uint8_t *buf)
2171 if (element == NULL)
2179 + (iter.global_element_index *
sizeof(
struct ses_comstat));
2188 ENC_DLOG(enc,
"Set Type 0x%x Obj 0x%x (offset %d) with %x %x %x %x\n",
2198 union ccb *
ccb, uint8_t *buf)
2224 offset < plength; offset +=
sizeof(
struct ses_comstat)) {
2225 buf[offset] &= ~SESCTL_CSEL;
2232 while ((req = TAILQ_FIRST(&ses->
ses_requests)) != NULL) {
2233 TAILQ_REMOVE(&ses->ses_requests, req, links);
2234 req->result = ses_encode(enc, buf, plength, req);
2235 if (req->result != 0) {
2242 if (TAILQ_EMPTY(&ses->ses_pending_requests) != 0)
2247 semb_send_diagnostic(&ccb->ataio, 5, NULL,
2249 buf, ses_page_length(&ses_cache->status_page->hdr),
2252 scsi_send_diagnostic(&ccb->csio, 5, NULL,
2253 MSG_SIMPLE_Q_TAG, 0,
2256 buf, ses_page_length(&ses_cache->status_page->hdr),
2257 SSD_FULL_SIZE, state->timeout);
2264 uint8_t *buf,
int bufsiz)
2266 ENC_VLOG(enc,
"FC Device Support Stubbed in Additional Status Page\n");
2270#define SES_PRINT_PORTS(p, type) do { \
2271 if (((p) & SES_SASOBJ_DEV_PHY_PROTOMASK) != 0) { \
2272 sbuf_printf(sbp, " %s (", type); \
2273 if ((p) & SES_SASOBJ_DEV_PHY_SMP) \
2274 sbuf_printf(sbp, " SMP"); \
2275 if ((p) & SES_SASOBJ_DEV_PHY_STP) \
2276 sbuf_printf(sbp, " STP"); \
2277 if ((p) & SES_SASOBJ_DEV_PHY_SSP) \
2278 sbuf_printf(sbp, " SSP"); \
2279 sbuf_printf(sbp, " )"); \
2301 addl = &(elmpriv->
addl);
2302 sbuf_printf(sbp,
", SAS Slot: %d%s phys",
2306 sbuf_printf(sbp,
" at slot %d",
2308 sbuf_printf(sbp,
"\n");
2313 sbuf_printf(sbp,
"%s: phy %d:", sesname, i);
2316 sbuf_printf(sbp,
" SATA device\n");
2318 sbuf_printf(sbp,
" SAS device type %d phy %d",
2322 sbuf_printf(sbp,
"\n");
2324 sbuf_printf(sbp,
"%s: phy %d: parent %jx addr %jx\n",
2330#undef SES_PRINT_PORTS
2351 addl = &(elmpriv->
addl);
2352 sbuf_printf(sbp,
", SAS ");
2355 sbuf_printf(sbp,
"Expander: %d phys", num_phys);
2358 for (i = 0;i < num_phys;i++) {
2360 sbuf_printf(sbp,
"%s: phy %d: connector %d other %d\n",
2366 sbuf_printf(sbp,
"Port: %d phys", num_phys);
2369 for (i = 0;i < num_phys;i++) {
2372 "%s: phy %d: id %d connector %d other %d\n",
2373 sesname, i, port_phy->
phy_id,
2375 sbuf_printf(sbp,
"%s: phy %d: addr %jx\n", sesname, i,
2395 sbuf_printf(sbp,
", SATA Slot: scbus%d target %d\n",
2410 struct sbuf sesname, name, out;
2413 if (elmpriv == NULL)
2416 addl = &(elmpriv->
addl);
2417 if (addl->
hdr == NULL)
2420 sbuf_new(&sesname, NULL, 16, SBUF_AUTOEXTEND);
2421 sbuf_new(&name, NULL, 16, SBUF_AUTOEXTEND);
2422 sbuf_new(&out, NULL, 512, SBUF_AUTOEXTEND);
2424 if (sbuf_len(&name) == 0)
2425 sbuf_printf(&name,
"(none)");
2429 sbuf_finish(&sesname);
2430 sbuf_printf(&out,
"%s: %s in ", sbuf_data(&sesname), sbuf_data(&name));
2431 if (elmpriv->
descr != NULL)
2432 sbuf_printf(&out,
"'%s'", elmpriv->
descr);
2437 sbuf_printf(&out,
"<Type 0x%02x>", obj->
elm_type);
2468 sbuf_cat(&out,
"\n");
2472 printf(
"%s", sbuf_data(&out));
2475 sbuf_delete(&sesname);
2492 uint8_t *buf,
int bufsiz,
int eip,
int nobj)
2494 int err, offset, physz;
2504 addl = &(elmpriv->
addl);
2522 if (physz > (bufsiz - offset + 4)) {
2523 ENC_VLOG(enc,
"Element %d Device Phy List Beyond End Of Buffer\n",
2551 uint8_t *buf,
int bufsiz,
int eip,
int nobj)
2553 int err, offset, physz;
2563 addl = &(elmpriv->
addl);
2577 if (physz > (bufsiz - offset)) {
2578 ENC_VLOG(enc,
"Element %d: Expander Phy List Beyond "
2579 "End Of Buffer\n", nobj);
2589 if (physz > (bufsiz - offset + 4)) {
2590 ENC_VLOG(enc,
"Element %d: Port Phy List Beyond End "
2591 "Of Buffer\n", nobj);
2618 uint8_t *buf,
int bufsiz,
int eip,
int tidx,
2642 ENC_VLOG(enc,
"Element %d has Additional Status type 0, "
2643 "invalid for SES element type 0x%x\n", nobj,
2660 ENC_VLOG(enc,
"Element %d has Additional Status type 1, "
2661 "invalid for SES element type 0x%x\n", nobj,
2670 ENC_VLOG(enc,
"Element %d of type 0x%x has Additional Status "
2671 "of unknown type 0x%x\n", nobj,
2696 uint8_t *buf,
int bufsiz,
int eip,
int tidx,
2713 ENC_VLOG(enc,
"Element %d has Additional Status, "
2714 "invalid for SES element type 0x%x\n", nobj,
2774 unsigned int i = elms->
elm_idx;
2810 if (elmpriv == NULL || elmpriv->descr == NULL) {
2840 sbuf_new(&sb, NULL, len, SBUF_FIXEDLEN);
2867 int amt, payload, ret;
2885 payload = sstr->
bufsiz + 4;
2894 buf[2] = sstr->
bufsiz >> 8;
2895 buf[3] = sstr->
bufsiz & 0xff;
2896 ret = copyin(sstr->
buf, &buf[4], sstr->
bufsiz);
2915 sizeof(enc_desc->
vendor_id),
sizeof(vendor));
2917 sizeof(enc_desc->
product_id),
sizeof(product));
2920 rsize = snprintf(str,
sizeof(str),
"%s %s %s",
2921 vendor, product, rev) + 1;
2922 if (rsize >
sizeof(str))
2923 rsize =
sizeof(str);
2927 copyout(str, sstr->
buf, size);
2929 return (size == rsize ? 0 : ENOMEM);
2934 rsize = snprintf(str,
sizeof(str),
"%16jx",
2936 if (rsize >
sizeof(str))
2937 rsize =
sizeof(str);
2941 copyout(str, sstr->
buf, size);
2943 return (size == rsize ? 0 : ENOMEM);
2949 ret = copyout(buf, sstr->
buf, sstr->
bufsiz);
3013 (
"entering enc_softc_init(%p)\n", enc));
void semb_receive_diagnostic_results(struct ccb_ataio *ataio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int pcv, uint8_t page_code, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
#define CAM_TARGET_WILDCARD
#define CAM_PRIORITY_NORMAL
#define CAM_SCSI_DEVID_MAXLEN
#define CDAI_TYPE_PHYS_PATH
#define CDAI_TYPE_SCSI_DEVID
#define CAM_DEBUG(path, flag, printfargs)
int cam_periph_list(struct cam_path *path, struct sbuf *sb)
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t openings, u_int32_t arg, int getcount_only)
int cam_periph_runccb(union ccb *ccb, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags), cam_flags camflags, u_int32_t sense_flags, struct devstat *ds)
#define cam_periph_lock(periph)
union ccb * cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
#define cam_periph_unlock(periph)
#define cam_periph_sleep(periph, chan, priority, wmesg, timo)
cam_status xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
path_id_t xpt_path_path_id(struct cam_path *path)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
void xpt_action(union ccb *start_ccb)
void xpt_free_path(struct cam_path *path)
void xpt_release_ccb(union ccb *free_ccb)
#define xpt_path_unlock(path)
#define xpt_path_lock(path)
void scsi_mode_sense(struct ccb_scsiio *csio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, uint8_t sense_len, uint32_t timeout)
void scsi_receive_diagnostic_results(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int pcv, uint8_t page_code, uint8_t *data_ptr, uint16_t allocation_length, uint8_t sense_len, uint32_t timeout)
void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int scsi_page_fmt, int save_pages, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout)
int scsi_devid_is_naa_ieee_reg(uint8_t *bufp)
struct scsi_vpd_id_descriptor * scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len, scsi_devid_checkfn_t ck_fn)
static __inline uint64_t scsi_8btou64(const uint8_t *bytes)
#define SVPD_ID_PROTO_SHIFT
static __inline uint32_t scsi_2btoul(const uint8_t *bytes)
#define SVPD_ID_CODESET_BINARY
#define RECEIVE_DIAGNOSTIC
static __inline uint32_t scsi_4btoul(const uint8_t *bytes)
#define SMS_PAGE_CTRL_CURRENT
#define SVPD_ID_ASSOC_PORT
#define SVPD_DEVICE_ID_DESC_HDR_LEN
int enc_runcmd(struct enc_softc *enc, char *cdb, int cdbl, char *dptr, int *dlenp)
const char * elm_type_names[]
void enc_update_request(enc_softc_t *enc, uint32_t action)
Queue an update request for a given action, if needed.
int enc_error(union ccb *ccb, uint32_t cflags, uint32_t sflags)
#define ENCIOC_GETENCNAME
#define SES_MGMT_TIMED_COMP_EN
#define SES_MGMT_MODE_PAGE_CODE
int fsm_fill_handler_t(enc_softc_t *ssc, struct enc_fsm_state *state, union ccb *ccb, uint8_t *buf)
static enc_cache_t * enc_other_cache(enc_softc_t *enc, enc_cache_t *primary)
int fsm_done_handler_t(enc_softc_t *ssc, struct enc_fsm_state *state, union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
void() enc_softc_cleanup_t(enc_softc_t *)
#define ENC_FREE_AND_NULL(ptr)
static void ses_cache_clone(enc_softc_t *enc, enc_cache_t *src, enc_cache_t *dst)
struct ses_element ses_element_t
static void ses_cache_free(enc_softc_t *enc, enc_cache_t *cache)
int ses_elm_addlstatus_proto(struct ses_elm_addlstatus_base_hdr *hdr)
static void ses_page_cdb(char *cdb, int bufsiz, SesDiagPageCodes pagenum, int dir)
Helper to set the CDB fields appropriately.
struct ses_setphyspath_callback_args ses_setphyspath_callback_args_t
static int ses_get_elm_addlstatus_sas_type0(enc_softc_t *enc, enc_cache_t *enc_cache, uint8_t *buf, int bufsiz, int eip, int nobj)
Update the softc with the additional element status data for this object, for SAS type 0 objects.
static fsm_done_handler_t ses_process_elm_descs
int ses_elm_sas_dev_phy_sata_dev(struct ses_elm_sas_device_phy *phy)
static void ses_print_addl_data(enc_softc_t *, enc_element_t *)
Print the additional element status data for this object.
static void ses_setphyspath_callback(enc_softc_t *enc, enc_element_t *elm, struct cam_path *path, void *arg)
ses_paths_iter() callback to set the physical path on the CAM EDT entries corresponding to a given SE...
@ ITERATOR_INDEX_INVALID
Value of an initialized but invalid index in a ses_iterator object.
@ ITERATOR_INDEX_END
Value of an index in a ses_iterator object when the iterator has traversed past the last valid elemen...
static void ses_device_found(enc_softc_t *enc)
Notification received when CAM detects a new device in the SCSI domain in which this SEP resides.
static int ses_search_globally
TAILQ_HEAD(ses_control_reqlist, ses_control_request)
static int ses_init_enc(enc_softc_t *enc)
int ses_elm_sas_dev_phy_sata_port(struct ses_elm_sas_device_phy *phy)
static void ses_poll_status(enc_softc_t *)
static int ses_get_elm_addlstatus_sas_type1(enc_softc_t *enc, enc_cache_t *enc_cache, uint8_t *buf, int bufsiz, int eip, int nobj)
Update the softc with the additional element status data for this object, for SAS type 1 objects.
static struct enc_fsm_state enc_fsm_states[SES_NUM_UPDATE_STATES]
void ses_path_callback_t(enc_softc_t *, enc_element_t *, struct cam_path *, void *)
static void ses_print_addl_data_ata(struct sbuf *sbp, enc_element_t *obj)
Print the additional element status data for this object, for ATA objects.
static int ses_get_elm_addlstatus_ata(enc_softc_t *, enc_cache_t *, uint8_t *, int, int, int, int)
Update the softc with the additional element status data for this object, for ATA objects.
void ses_devid_callback_t(enc_softc_t *, enc_element_t *, struct scsi_vpd_id_descriptor *, void *)
struct ses_control_reqlist ses_control_reqlist_t
static void ses_paths_iter(enc_softc_t *enc, enc_element_t *elm, ses_path_callback_t *callback, void *callback_arg)
Iterate over and find the matching periph objects for the specified element.
static void ses_cache_free_elm_descs(enc_softc_t *enc, enc_cache_t *cache)
static fsm_done_handler_t ses_publish_cache
static enc_element_t * ses_iter_next(struct ses_iterator *iter)
Traverse the provided SES iterator to the next element within the configuration.
static void ses_devids_iter(enc_softc_t *enc, enc_element_t *elm, ses_devid_callback_t *callback, void *callback_arg)
Iterate over and create vpd device id records from the additional element status data for elm,...
static void ses_terminate_control_requests(ses_control_reqlist_t *reqlist, int result)
static int ses_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
struct ses_softc ses_softc_t
static void ses_iter_init(enc_softc_t *enc, enc_cache_t *cache, struct ses_iterator *iter)
Initialize the storage of a SES iterator and reset it to the position just before the first element o...
static fsm_done_handler_t ses_process_control_request
static ses_addlstatus_avail_t ses_typehasaddlstatus(enc_softc_t *enc, uint8_t typidx)
Check to see whether a given type (as obtained via type headers) is supported by the additional statu...
struct ses_type ses_type_t
static int ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, unsigned long ioc)
Send a string to the primary subenclosure using the String Out SES diagnostic page.
static fsm_done_handler_t ses_process_elm_addlstatus
int ses_elm_sas_dev_phy_dev_type(struct ses_elm_sas_device_phy *phy)
@ SES_ELEM_INDEX_INDIVIDUAL
Index relative to all individual elements in the system.
struct ses_comstat ses_comstat_t
int ses_elm_addlstatus_eip(struct ses_elm_addlstatus_base_hdr *hdr)
static void ses_cache_free_elm_map(enc_softc_t *enc, enc_cache_t *cache)
static void ses_cache_free_elm_addlstatus(enc_softc_t *enc, enc_cache_t *cache)
static fsm_done_handler_t ses_process_config
static int ses_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag)
@ TYPE_ADDLSTATUS_OPTIONAL
@ TYPE_ADDLSTATUS_MANDATORY
static fsm_done_handler_t ses_process_pages
struct ses_control_request ses_control_request_t
struct ses_cache ses_cache_t
static int ses_get_elm_addlstatus_fc(enc_softc_t *, enc_cache_t *, uint8_t *, int)
#define SES_FLAG_TIMEDCOMP
static fsm_done_handler_t ses_publish_physpaths
struct ses_path_iter_args ses_path_iter_args_t
static int ses_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
static void ses_print_addl_data_sas_type1(char *sesname, struct sbuf *sbp, enc_element_t *obj)
Print the additional element status data for this object, for SAS type 1 objects. See SES2 r20 Sectio...
static void ses_path_iter_devid_callback(enc_softc_t *enc, enc_element_t *elem, struct scsi_vpd_id_descriptor *devid, void *arg)
static int ses_get_elm_devnames(enc_softc_t *enc, encioc_elm_devnames_t *elmdn)
Respond to ENCIOC_GETELMDEVNAME, providing a device name for the given object id if one is available.
static void ses_elmdevname_callback(enc_softc_t *enc, enc_element_t *elem, struct cam_path *path, void *arg)
static void ses_softc_invalidate(enc_softc_t *enc)
static enc_softc_cleanup_t ses_softc_cleanup
static struct enc_vec ses_enc_vec
static fsm_done_handler_t ses_process_status
static int ses_get_elm_addlstatus_sas(enc_softc_t *, enc_cache_t *, uint8_t *, int, int, int, int)
Update the softc with the additional element status data for this object, for SAS objects.
int ses_elm_sas_descr_type(union ses_elm_sas_hdr *obj)
static enc_element_t * ses_iter_seek_to(struct ses_iterator *iter, int element_index, ses_elem_index_type_t index_type)
Move the provided iterator forwards or backwards to the object having the give index.
#define SES_FLAG_ADDLSTATUS
static int ses_config_cache_valid(ses_cache_t *ses_cache, const uint8_t *gen_code)
Verify that the cached configuration data in our softc is valid for processing the page data correspo...
int ses_elm_sas_type0_not_all_phys(union ses_elm_sas_hdr *hdr)
static void ses_cache_free_status(enc_softc_t *enc, enc_cache_t *cache)
static void ses_print_addl_data_sas_type0(char *sesname, struct sbuf *sbp, enc_element_t *obj)
Print the additional element status data for this object, for SAS type 0 objects. See SES2 r20 Sectio...
SYSCTL_INT(_kern_cam_enc, OID_AUTO, search_globally, CTLFLAG_RWTUN, &ses_search_globally, 0, "Search for disks on other buses")
static fsm_fill_handler_t ses_fill_control_request
static const char * ses_sanitize_elm_desc(const char *desc, uint16_t *len)
struct ses_addl_status ses_add_status_t
int ses_softc_init(enc_softc_t *enc)
Initialize a new SES instance.
static void ses_iter_reset(struct ses_iterator *iter)
Reset a SES iterator to just before the first element in the configuration.
static int ses_get_elm_desc(enc_softc_t *enc, encioc_elm_desc_t *elmd)
static int ses_encode(enc_softc_t *enc, uint8_t *buf, int amt, ses_control_request_t *req)
Encode the object status into the response buffer, which is expected to contain the current enclosure...
static int ses_set_timed_completion(enc_softc_t *, uint8_t)
Discover whether this instance supports timed completion of a RECEIVE DIAGNOSTIC RESULTS command requ...
union ses_addl_data ses_add_data_t
int ses_elm_addlstatus_invalid(struct ses_elm_addlstatus_base_hdr *hdr)
static fsm_fill_handler_t ses_fill_rcv_diag_io
#define SES_PRINT_PORTS(p, type)
@ SES_UPDATE_GETELMADDLSTATUS
@ SES_PROCESS_CONTROL_REQS
static int ses_set_physpath(enc_softc_t *enc, enc_element_t *elm, struct ses_iterator *iter)
Set a device's physical path string in CAM XPT.
#define SES_SET_STATUS_MASK
#define SES_SASOBJ_TYPE_SLOT
static int ses_enc_desc_is_complete(struct ses_enc_desc *encdesc, uint8_t *last_buf_byte)
#define SES_ADDL_EIP_EIIOE_EI_GLOB(x)
static int ses_cfg_page_get_num_subenc(struct ses_cfg_page *page)
static size_t ses_page_length(const struct ses_page_hdr *hdr)
#define SES_SASOBJ_TYPE_OTHER
#define SES_EIP_HDR_EXTRA_LEN
static struct ses_enc_desc * ses_enc_desc_next(struct ses_enc_desc *encdesc)
struct dev_match_result * matches
ccb_dev_match_status status
u_int32_t pattern_buf_len
struct dev_match_pattern * patterns
union device_match_pattern::@1 data
struct device_id_match_pattern devid_pat
encioc_enc_status_t enc_status
struct cam_periph * periph
struct enc_fsm_state * enc_fsm_states
enc_cache_t enc_daemon_cache
enc_softc_invalidate_t * softc_invalidate
struct ses_elm_addlstatus_base_hdr * hdr
union ses_addl_status::@24 proto_hdr
struct ses_elm_ata_hdr * ata
union ses_elm_sas_hdr * sas
union ses_addl_data proto_data
const struct ses_status_page * status_page
const struct ses_elem_descr_page * elm_descs_page
const struct ses_cfg_page * cfg_page
const struct ses_enc_desc *const * subencs
const struct ses_addl_elem_status_page * elm_addlstatus_page
const ses_type_t * ses_types
struct ses_enc_desc subencs[]
struct ses_addl_status addl
Structure encapsulating all data necessary to traverse the elements of a SES configuration.
int saved_individual_element_index
The last valid individual element index of this iterator.
int individual_element_index
The position (0 based) of this element relative to all other individual status elements in the config...
int global_element_index
The position (0 based) of this element relative to all elements in the configration.
int type_index
Index of the type of the current element within the ses_cache's ses_types array.
int type_element_index
The position (0 based) of this element relative to all other elements of this type.
enc_softc_t * enc
Backlink to the overal software configuration structure.
uint8_t page_specific_flags
ses_path_callback_t * callback
ses_control_reqlist_t ses_pending_requests
ses_control_reqlist_t ses_requests
union ses_status_element elements[]
const struct ses_elm_type_desc * hdr
struct device_match_pattern device_pattern
struct device_match_result device_result
struct ses_elm_sas_device_phy * sasdev_phys
struct ses_elm_sas_port_phy * sasport_phys
struct ses_elm_sas_expander_phy * sasexp_phys
struct ses_fcobj_port * fc_ports
struct ses_elm_sas_type0_eip_hdr type0_eip
struct ses_elm_sas_base_hdr base_hdr