Index: sys/cam/cam_ccb.h =================================================================== --- sys/cam/cam_ccb.h +++ sys/cam/cam_ccb.h @@ -247,6 +247,12 @@ XPT_REPROBE_LUN = 0x38 | XPT_FC_QUEUED | XPT_FC_USER_CCB, /* Query device capacity and notify GEOM */ +/* Generic SIM: 0x40->0x4f */ + XPT_KV_GET = 0x40, + /* Get the Value for the passed in Key */ + XPT_KV_SET = 0x41, + /* Set the value based on the key */ + /* Vendor Unique codes: 0x80->0x8F */ XPT_VUNIQUE = 0x80 } xpt_opcode; @@ -1294,6 +1300,24 @@ void *async_arg_ptr; }; +/* + * CCB for key value pairs + */ +struct ccb_kv { + struct ccb_hdr ccb_h; +#define CCB_KV_KEY_LEN 64 +#define CCB_KV_VAL_LEN 128 + char key[CCB_KV_KEY_LEN]; + uint32_t val_len; + union { + void *ptr; /* In kernel only */ + uintptr_t num; + char value[CCB_KV_VAL_LEN]; + } u; +}; +#define CCB_KV_DEVICE_T "device_t" +#define CCB_KV_NUMA_DOMAIN "numa_domain" + /* * Union of all CCB types for kernel space allocation. This union should * never be used for manipulating CCBs - its only use is for the allocation @@ -1336,6 +1360,7 @@ struct ccb_async casync; struct ccb_nvmeio nvmeio; struct ccb_mmcio mmcio; + struct ccb_kv kv; }; #define CCB_CLEAR_ALL_EXCEPT_HDR(ccbp) \ Index: sys/cam/cam_xpt.h =================================================================== --- sys/cam/cam_xpt.h +++ sys/cam/cam_xpt.h @@ -163,6 +163,43 @@ xpt_action((union ccb *)cpi); } +/* + * Get the @key associated with the @path using the @ckv CCB to ask the + * SIM. + */ +static inline void +xpt_kv_get(struct ccb_kv *ckv, struct cam_path *path, const char *key) +{ + + bzero(ckv, sizeof(*ckv)); + xpt_setup_ccb(&ckv->ccb_h, path, CAM_PRIORITY_NORMAL); + ckv->ccb_h.func_code = XPT_KV_GET; + strlcpy(ckv->key, key, sizeof(ckv->key)); + xpt_action((union ccb *)ckv); +} + +/* + * Set the @key associated with the @path using the @ckv CCB to ask the + * SIM. + */ +static inline void +xpt_kv_set(struct ccb_kv *ckv, struct cam_path *path, const char *key, + void *value, size_t len) +{ + + bzero(ckv, sizeof(*ckv)); + xpt_setup_ccb(&ckv->ccb_h, path, CAM_PRIORITY_NORMAL); + ckv->ccb_h.func_code = XPT_KV_SET; + if (len > sizeof(ckv->u)) { + /* Not queued, so just set status and return */ + ckv->ccb_h.status = CAM_REQ_ABORTED | CAM_REQ_TOO_BIG; + return; + } + strlcpy(ckv->key, key, sizeof(ckv->key)); + memcpy(&ckv->u, value, len); + xpt_action((union ccb *)ckv); +} + #endif /* _KERNEL */ #endif /* _CAM_CAM_XPT_H */