1*44704f69SBart Van Assche #ifndef SG_VPD_H 2*44704f69SBart Van Assche #define SG_VPD_H 3*44704f69SBart Van Assche 4*44704f69SBart Van Assche /* 5*44704f69SBart Van Assche * Copyright (c) 2022 Douglas Gilbert. 6*44704f69SBart Van Assche * All rights reserved. 7*44704f69SBart Van Assche * Use of this source code is governed by a BSD-style 8*44704f69SBart Van Assche * license that can be found in the BSD_LICENSE file. 9*44704f69SBart Van Assche * 10*44704f69SBart Van Assche * SPDX-License-Identifier: BSD-2-Clause 11*44704f69SBart Van Assche */ 12*44704f69SBart Van Assche 13*44704f69SBart Van Assche /* This is a common header file for the sg_inq and sg_vpd utilities */ 14*44704f69SBart Van Assche 15*44704f69SBart Van Assche #include <stdint.h> 16*44704f69SBart Van Assche #include <stdbool.h> 17*44704f69SBart Van Assche 18*44704f69SBart Van Assche #ifdef HAVE_CONFIG_H 19*44704f69SBart Van Assche #include "config.h" 20*44704f69SBart Van Assche #endif 21*44704f69SBart Van Assche 22*44704f69SBart Van Assche #include "sg_lib.h" 23*44704f69SBart Van Assche #include "sg_pr2serr.h" 24*44704f69SBart Van Assche 25*44704f69SBart Van Assche #ifdef __cplusplus 26*44704f69SBart Van Assche extern "C" { 27*44704f69SBart Van Assche #endif 28*44704f69SBart Van Assche 29*44704f69SBart Van Assche /* standard VPD pages, in ascending page number order */ 30*44704f69SBart Van Assche #define VPD_SUPPORTED_VPDS 0x0 31*44704f69SBart Van Assche #define VPD_UNIT_SERIAL_NUM 0x80 32*44704f69SBart Van Assche #define VPD_IMP_OP_DEF 0x81 /* obsolete in SPC-2 */ 33*44704f69SBart Van Assche #define VPD_ASCII_OP_DEF 0x82 /* obsolete in SPC-2 */ 34*44704f69SBart Van Assche #define VPD_DEVICE_ID 0x83 35*44704f69SBart Van Assche #define VPD_SOFTW_INF_ID 0x84 36*44704f69SBart Van Assche #define VPD_MAN_NET_ADDR 0x85 37*44704f69SBart Van Assche #define VPD_EXT_INQ 0x86 /* Extended Inquiry */ 38*44704f69SBart Van Assche #define VPD_MODE_PG_POLICY 0x87 39*44704f69SBart Van Assche #define VPD_SCSI_PORTS 0x88 40*44704f69SBart Van Assche #define VPD_ATA_INFO 0x89 41*44704f69SBart Van Assche #define VPD_POWER_CONDITION 0x8a 42*44704f69SBart Van Assche #define VPD_DEVICE_CONSTITUENTS 0x8b 43*44704f69SBart Van Assche #define VPD_CFA_PROFILE_INFO 0x8c 44*44704f69SBart Van Assche #define VPD_POWER_CONSUMPTION 0x8d 45*44704f69SBart Van Assche #define VPD_3PARTY_COPY 0x8f /* 3PC, XCOPY, SPC-5, SBC-4 */ 46*44704f69SBart Van Assche #define VPD_PROTO_LU 0x90 47*44704f69SBart Van Assche #define VPD_PROTO_PORT 0x91 48*44704f69SBart Van Assche #define VPD_SCSI_FEATURE_SETS 0x92 /* spc5r11 */ 49*44704f69SBart Van Assche #define VPD_BLOCK_LIMITS 0xb0 /* SBC-3 */ 50*44704f69SBart Van Assche #define VPD_SA_DEV_CAP 0xb0 /* SSC-3 */ 51*44704f69SBart Van Assche #define VPD_OSD_INFO 0xb0 /* OSD */ 52*44704f69SBart Van Assche #define VPD_BLOCK_DEV_CHARS 0xb1 /* SBC-3 */ 53*44704f69SBart Van Assche #define VPD_MAN_ASS_SN 0xb1 /* SSC-3, ADC-2 */ 54*44704f69SBart Van Assche #define VPD_SECURITY_TOKEN 0xb1 /* OSD */ 55*44704f69SBart Van Assche #define VPD_TA_SUPPORTED 0xb2 /* SSC-3 */ 56*44704f69SBart Van Assche #define VPD_LB_PROVISIONING 0xb2 /* SBC-3 */ 57*44704f69SBart Van Assche #define VPD_REFERRALS 0xb3 /* SBC-3 */ 58*44704f69SBart Van Assche #define VPD_AUTOMATION_DEV_SN 0xb3 /* SSC-3 */ 59*44704f69SBart Van Assche #define VPD_SUP_BLOCK_LENS 0xb4 /* sbc4r01 */ 60*44704f69SBart Van Assche #define VPD_DTDE_ADDRESS 0xb4 /* SSC-4 */ 61*44704f69SBart Van Assche #define VPD_BLOCK_DEV_C_EXTENS 0xb5 /* sbc4r02 */ 62*44704f69SBart Van Assche #define VPD_LB_PROTECTION 0xb5 /* SSC-5 */ 63*44704f69SBart Van Assche #define VPD_ZBC_DEV_CHARS 0xb6 /* zbc-r01b */ 64*44704f69SBart Van Assche #define VPD_BLOCK_LIMITS_EXT 0xb7 /* sbc4r08 */ 65*44704f69SBart Van Assche #define VPD_FORMAT_PRESETS 0xb8 /* sbc4r18 */ 66*44704f69SBart Van Assche #define VPD_CON_POS_RANGE 0xb9 /* sbc5r01 */ 67*44704f69SBart Van Assche #define VPD_NOPE_WANT_STD_INQ -2 /* request for standard inquiry */ 68*44704f69SBart Van Assche 69*44704f69SBart Van Assche /* vendor/product identifiers */ 70*44704f69SBart Van Assche #define VPD_VP_SEAGATE 0 71*44704f69SBart Van Assche #define VPD_VP_RDAC 1 72*44704f69SBart Van Assche #define VPD_VP_EMC 2 73*44704f69SBart Van Assche #define VPD_VP_DDS 3 74*44704f69SBart Van Assche #define VPD_VP_HP3PAR 4 75*44704f69SBart Van Assche #define VPD_VP_IBM_LTO 5 76*44704f69SBart Van Assche #define VPD_VP_HP_LTO 6 77*44704f69SBart Van Assche #define VPD_VP_WDC_HITACHI 7 78*44704f69SBart Van Assche #define VPD_VP_NVME 8 79*44704f69SBart Van Assche #define VPD_VP_SG 9 /* this package/library as a vendor */ 80*44704f69SBart Van Assche 81*44704f69SBart Van Assche 82*44704f69SBart Van Assche /* vendor VPD pages */ 83*44704f69SBart Van Assche #define VPD_V_HIT_PG3 0x3 84*44704f69SBart Van Assche #define VPD_V_HP3PAR 0xc0 85*44704f69SBart Van Assche #define VPD_V_FIRM_SEA 0xc0 86*44704f69SBart Van Assche #define VPD_V_UPR_EMC 0xc0 87*44704f69SBart Van Assche #define VPD_V_HVER_RDAC 0xc0 88*44704f69SBart Van Assche #define VPD_V_FVER_DDS 0xc0 89*44704f69SBart Van Assche #define VPD_V_FVER_LTO 0xc0 90*44704f69SBart Van Assche #define VPD_V_DCRL_LTO 0xc0 91*44704f69SBart Van Assche #define VPD_V_DATC_SEA 0xc1 92*44704f69SBart Van Assche #define VPD_V_FVER_RDAC 0xc1 93*44704f69SBart Van Assche #define VPD_V_HVER_LTO 0xc1 94*44704f69SBart Van Assche #define VPD_V_DSN_LTO 0xc1 95*44704f69SBart Van Assche #define VPD_V_JUMP_SEA 0xc2 96*44704f69SBart Van Assche #define VPD_V_SVER_RDAC 0xc2 97*44704f69SBart Van Assche #define VPD_V_PCA_LTO 0xc2 98*44704f69SBart Van Assche #define VPD_V_DEV_BEH_SEA 0xc3 99*44704f69SBart Van Assche #define VPD_V_FEAT_RDAC 0xc3 100*44704f69SBart Van Assche #define VPD_V_MECH_LTO 0xc3 101*44704f69SBart Van Assche #define VPD_V_SUBS_RDAC 0xc4 102*44704f69SBart Van Assche #define VPD_V_HEAD_LTO 0xc4 103*44704f69SBart Van Assche #define VPD_V_ACI_LTO 0xc5 104*44704f69SBart Van Assche #define VPD_V_DUCD_LTO 0xc7 105*44704f69SBart Van Assche #define VPD_V_EDID_RDAC 0xc8 106*44704f69SBart Van Assche #define VPD_V_MPDS_LTO 0xc8 107*44704f69SBart Van Assche #define VPD_V_VAC_RDAC 0xc9 108*44704f69SBart Van Assche #define VPD_V_RVSI_RDAC 0xca 109*44704f69SBart Van Assche #define VPD_V_SAID_RDAC 0xd0 110*44704f69SBart Van Assche #define VPD_V_HIT_PG_D1 0xd1 111*44704f69SBart Van Assche #define VPD_V_HIT_PG_D2 0xd2 112*44704f69SBart Van Assche 113*44704f69SBart Van Assche #ifndef SG_NVME_VPD_NICR 114*44704f69SBart Van Assche #define SG_NVME_VPD_NICR 0xde /* NVME Identify Controller Response */ 115*44704f69SBart Van Assche #endif 116*44704f69SBart Van Assche 117*44704f69SBart Van Assche #define DEF_ALLOC_LEN 252 118*44704f69SBart Van Assche #define MX_ALLOC_LEN (0xc000 + 0x80) 119*44704f69SBart Van Assche #define DEF_PT_TIMEOUT 60 /* 60 seconds */ 120*44704f69SBart Van Assche 121*44704f69SBart Van Assche enum sg_vpd_invoker_e { 122*44704f69SBart Van Assche SG_VPD_INV_NONE = 0, 123*44704f69SBart Van Assche SG_VPD_INV_SG_INQ, 124*44704f69SBart Van Assche SG_VPD_INV_SG_VPD, 125*44704f69SBart Van Assche }; 126*44704f69SBart Van Assche 127*44704f69SBart Van Assche /* This structure holds the union of options available in sg_inq and sg_vpd */ 128*44704f69SBart Van Assche struct opts_t { 129*44704f69SBart Van Assche enum sg_vpd_invoker_e invoker; /* indicates if for sg_inq or sg_vpd */ 130*44704f69SBart Van Assche bool do_all; /* sg_vpd */ 131*44704f69SBart Van Assche bool do_ata; /* sg_inq */ 132*44704f69SBart Van Assche bool do_decode; /* sg_inq */ 133*44704f69SBart Van Assche bool do_descriptors; /* sg_inq */ 134*44704f69SBart Van Assche bool do_enum; /* sg_enum */ 135*44704f69SBart Van Assche bool do_export; /* sg_inq */ 136*44704f69SBart Van Assche bool do_force; /* sg_inq + sg_vpd */ 137*44704f69SBart Van Assche bool do_only; /* sg_inq: --only after stdinq: don't fetch VPD page 0x80 */ 138*44704f69SBart Van Assche bool do_quiet; /* sg_vpd */ 139*44704f69SBart Van Assche bool examine_given; /* sg_vpd */ 140*44704f69SBart Van Assche bool page_given; /* sg_inq + sg_vpd */ 141*44704f69SBart Van Assche bool possible_nvme; /* sg_inq */ 142*44704f69SBart Van Assche bool protect_not_sure; /* sg_vpd */ 143*44704f69SBart Van Assche bool verbose_given; /* sg_inq + sg_vpd */ 144*44704f69SBart Van Assche bool version_given; /* sg_inq + sg_vpd */ 145*44704f69SBart Van Assche bool do_vpd; /* sg_inq */ 146*44704f69SBart Van Assche bool std_inq_a_valid; /* sg_inq + sg_vpd */ 147*44704f69SBart Van Assche #ifdef SG_SCSI_STRINGS 148*44704f69SBart Van Assche bool opt_new; /* sg_inq */ 149*44704f69SBart Van Assche #endif 150*44704f69SBart Van Assche int do_block; /* do_block */ 151*44704f69SBart Van Assche int do_cmddt; /* sg_inq */ 152*44704f69SBart Van Assche int do_help; /* sg_inq */ 153*44704f69SBart Van Assche int do_hex; /* sg_inq + sg_vpd */ 154*44704f69SBart Van Assche int do_ident; /* sg_vpd */ 155*44704f69SBart Van Assche int do_long; /* sg_inq[int] + sg_vpd[bool] */ 156*44704f69SBart Van Assche int do_raw; /* sg_inq + sg_vpd */ 157*44704f69SBart Van Assche int do_vendor; /* sg_inq */ 158*44704f69SBart Van Assche int examine; /* sg_vpd */ 159*44704f69SBart Van Assche int maxlen; /* sg_inq[was: resp_len] + sg_vpd */ 160*44704f69SBart Van Assche int num_pages; /* sg_inq */ 161*44704f69SBart Van Assche int page_pdt; /* sg_inq */ 162*44704f69SBart Van Assche int vend_prod_num; /* sg_vpd */ 163*44704f69SBart Van Assche int verbose; /* sg_inq + sg_vpd */ 164*44704f69SBart Van Assche int vpd_pn; /* sg_vpd */ 165*44704f69SBart Van Assche const char * device_name; /* sg_inq + sg_vpd */ 166*44704f69SBart Van Assche const char * page_str; /* sg_inq + sg_vpd */ 167*44704f69SBart Van Assche const char * inhex_fn; /* sg_inq + sg_vpd */ 168*44704f69SBart Van Assche const char * sinq_inraw_fn; /* sg_inq + sg_vpd */ 169*44704f69SBart Van Assche const char * vend_prod; /* sg_vpd */ 170*44704f69SBart Van Assche sgj_state json_st; 171*44704f69SBart Van Assche uint8_t std_inq_a[36]; 172*44704f69SBart Van Assche }; 173*44704f69SBart Van Assche 174*44704f69SBart Van Assche struct svpd_values_name_t { 175*44704f69SBart Van Assche int value; /* VPD page number */ 176*44704f69SBart Van Assche int subvalue; /* to differentiate if value+pdt are not unique */ 177*44704f69SBart Van Assche int pdt; /* peripheral device type id, -1 is the default */ 178*44704f69SBart Van Assche /* (all or not applicable) value */ 179*44704f69SBart Van Assche const char * acron; 180*44704f69SBart Van Assche const char * name; 181*44704f69SBart Van Assche }; 182*44704f69SBart Van Assche 183*44704f69SBart Van Assche struct svpd_vp_name_t { 184*44704f69SBart Van Assche int vend_prod_num; /* vendor/product identifier */ 185*44704f69SBart Van Assche const char * acron; 186*44704f69SBart Van Assche const char * name; 187*44704f69SBart Van Assche }; 188*44704f69SBart Van Assche 189*44704f69SBart Van Assche typedef int (*recurse_vpd_decodep)(struct opts_t *, sgj_opaque_p jop, int off); 190*44704f69SBart Van Assche 191*44704f69SBart Van Assche 192*44704f69SBart Van Assche sgj_opaque_p sg_vpd_js_hdr(sgj_state * jsp, sgj_opaque_p jop, 193*44704f69SBart Van Assche const char * name, const uint8_t * vpd_hdrp); 194*44704f69SBart Van Assche void decode_net_man_vpd(const uint8_t * buff, int len, struct opts_t * op, 195*44704f69SBart Van Assche sgj_opaque_p jap); 196*44704f69SBart Van Assche void decode_x_inq_vpd(const uint8_t * b, int len, bool protect, 197*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 198*44704f69SBart Van Assche void decode_softw_inf_id(const uint8_t * buff, int len, struct opts_t * op, 199*44704f69SBart Van Assche sgj_opaque_p jap); 200*44704f69SBart Van Assche void decode_mode_policy_vpd(const uint8_t * buff, int len, struct opts_t * op, 201*44704f69SBart Van Assche sgj_opaque_p jap); 202*44704f69SBart Van Assche void decode_cga_profile_vpd(const uint8_t * buff, int len, struct opts_t * op, 203*44704f69SBart Van Assche sgj_opaque_p jap); 204*44704f69SBart Van Assche void decode_power_condition(const uint8_t * buff, int len, struct opts_t * op, 205*44704f69SBart Van Assche sgj_opaque_p jop); 206*44704f69SBart Van Assche int filter_json_dev_ids(uint8_t * buff, int len, int m_assoc, 207*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap); 208*44704f69SBart Van Assche void decode_ata_info_vpd(const uint8_t * buff, int len, struct opts_t * op, 209*44704f69SBart Van Assche sgj_opaque_p jop); 210*44704f69SBart Van Assche void decode_feature_sets_vpd(const uint8_t * buff, int len, struct opts_t * op, 211*44704f69SBart Van Assche sgj_opaque_p jap); 212*44704f69SBart Van Assche void decode_dev_constit_vpd(const uint8_t * buff, int len, 213*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap, 214*44704f69SBart Van Assche recurse_vpd_decodep fp); 215*44704f69SBart Van Assche sgj_opaque_p std_inq_decode_js(const uint8_t * b, int len, 216*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 217*44704f69SBart Van Assche void decode_power_consumption(const uint8_t * buff, int len, 218*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap); 219*44704f69SBart Van Assche void decode_block_limits_vpd(const uint8_t * buff, int len, 220*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 221*44704f69SBart Van Assche void decode_block_dev_ch_vpd(const uint8_t * buff, int len, 222*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 223*44704f69SBart Van Assche int decode_block_lb_prov_vpd(const uint8_t * buff, int len, 224*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 225*44704f69SBart Van Assche void decode_referrals_vpd(const uint8_t * buff, int len, struct opts_t * op, 226*44704f69SBart Van Assche sgj_opaque_p jop); 227*44704f69SBart Van Assche void decode_sup_block_lens_vpd(const uint8_t * buff, int len, 228*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap); 229*44704f69SBart Van Assche void decode_block_dev_char_ext_vpd(const uint8_t * buff, int len, 230*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 231*44704f69SBart Van Assche void decode_zbdch_vpd(const uint8_t * buff, int len, struct opts_t * op, 232*44704f69SBart Van Assche sgj_opaque_p jop); 233*44704f69SBart Van Assche void decode_block_limits_ext_vpd(const uint8_t * buff, int len, 234*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 235*44704f69SBart Van Assche void decode_format_presets_vpd(const uint8_t * buff, int len, 236*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap); 237*44704f69SBart Van Assche void decode_con_pos_range_vpd(const uint8_t * buff, int len, 238*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jap); 239*44704f69SBart Van Assche void decode_3party_copy_vpd(const uint8_t * buff, int len, struct opts_t * op, 240*44704f69SBart Van Assche sgj_opaque_p jap); 241*44704f69SBart Van Assche void 242*44704f69SBart Van Assche decode_proto_lu_vpd(const uint8_t * buff, int len, struct opts_t * op, 243*44704f69SBart Van Assche sgj_opaque_p jap); 244*44704f69SBart Van Assche void 245*44704f69SBart Van Assche decode_proto_port_vpd(const uint8_t * buff, int len, struct opts_t * op, 246*44704f69SBart Van Assche sgj_opaque_p jap); 247*44704f69SBart Van Assche void 248*44704f69SBart Van Assche decode_lb_protection_vpd(const uint8_t * buff, int len, struct opts_t * op, 249*44704f69SBart Van Assche sgj_opaque_p jap); 250*44704f69SBart Van Assche void 251*44704f69SBart Van Assche decode_tapealert_supported_vpd(const uint8_t * buff, int len, 252*44704f69SBart Van Assche struct opts_t * op, sgj_opaque_p jop); 253*44704f69SBart Van Assche /* Share some vendor specific VPD pages as well */ 254*44704f69SBart Van Assche void 255*44704f69SBart Van Assche decode_upr_vpd_c0_emc(uint8_t * buff, int len, struct opts_t * op, 256*44704f69SBart Van Assche sgj_opaque_p jop); 257*44704f69SBart Van Assche void 258*44704f69SBart Van Assche decode_rdac_vpd_c2(uint8_t * buff, int len, struct opts_t * op, 259*44704f69SBart Van Assche sgj_opaque_p jop); 260*44704f69SBart Van Assche void 261*44704f69SBart Van Assche decode_rdac_vpd_c9(uint8_t * buff, int len, struct opts_t * op, 262*44704f69SBart Van Assche sgj_opaque_p jop); 263*44704f69SBart Van Assche 264*44704f69SBart Van Assche const char * pqual_str(int pqual); 265*44704f69SBart Van Assche int no_ascii_4hex(const struct opts_t * op); 266*44704f69SBart Van Assche 267*44704f69SBart Van Assche void svpd_enumerate_vendor(int vend_prod_num); 268*44704f69SBart Van Assche int svpd_count_vendor_vpds(int vpd_pn, int vend_prod_num); 269*44704f69SBart Van Assche int svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, 270*44704f69SBart Van Assche int off); 271*44704f69SBart Van Assche const struct svpd_values_name_t * svpd_find_vendor_by_acron(const char * ap); 272*44704f69SBart Van Assche int svpd_find_vp_num_by_acron(const char * vp_ap); 273*44704f69SBart Van Assche const struct svpd_values_name_t * svpd_find_vendor_by_num(int page_num, 274*44704f69SBart Van Assche int vend_prod_num); 275*44704f69SBart Van Assche int vpd_fetch_page(int sg_fd, uint8_t * rp, int page, int mxlen, 276*44704f69SBart Van Assche bool qt, int vb, int * rlenp); 277*44704f69SBart Van Assche void dup_sanity_chk(int sz_opts_t, int sz_values_name_t); 278*44704f69SBart Van Assche 279*44704f69SBart Van Assche extern uint8_t * rsp_buff; 280*44704f69SBart Van Assche extern const char * t10_vendor_id_hr; 281*44704f69SBart Van Assche extern const char * t10_vendor_id_js; 282*44704f69SBart Van Assche extern const char * product_id_hr; 283*44704f69SBart Van Assche extern const char * product_id_js; 284*44704f69SBart Van Assche extern const char * product_rev_lev_hr; 285*44704f69SBart Van Assche extern const char * product_rev_lev_js; 286*44704f69SBart Van Assche extern struct svpd_vp_name_t vp_arr[]; 287*44704f69SBart Van Assche extern struct svpd_values_name_t vendor_vpd_pg[]; 288*44704f69SBart Van Assche 289*44704f69SBart Van Assche 290*44704f69SBart Van Assche #ifdef __cplusplus 291*44704f69SBart Van Assche } 292*44704f69SBart Van Assche #endif 293*44704f69SBart Van Assche 294*44704f69SBart Van Assche #endif /* end of SG_VPD_H */ 295