1176a9270SRobert Mustacchi /*
2176a9270SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3176a9270SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4176a9270SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5176a9270SRobert Mustacchi  * 1.0 of the CDDL.
6176a9270SRobert Mustacchi  *
7176a9270SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8176a9270SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9176a9270SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10176a9270SRobert Mustacchi  */
11176a9270SRobert Mustacchi 
12176a9270SRobert Mustacchi /*
13176a9270SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
14*d53cdfabSRobert Mustacchi  * Copyright 2021 Oxide Computer Company
15176a9270SRobert Mustacchi  */
16176a9270SRobert Mustacchi 
17176a9270SRobert Mustacchi /*
18176a9270SRobert Mustacchi  * Basic testing of the SMBIOS 3.2 Slot extensions.
19176a9270SRobert Mustacchi  */
20176a9270SRobert Mustacchi 
21176a9270SRobert Mustacchi #include "smbios_test.h"
22176a9270SRobert Mustacchi 
23176a9270SRobert Mustacchi static const char *smbios_test_name = "The One Slot";
24c6795799SRobert Mustacchi static uint8_t smbios_slot_bus = 0x42;
25c6795799SRobert Mustacchi static uint8_t smbios_slot_df = 0x23;
26c6795799SRobert Mustacchi static uint8_t smbios_slot_info = 0x65;
27c6795799SRobert Mustacchi static uint16_t smbios_slot_pitch = 0x12af;
28c6795799SRobert Mustacchi 
29*d53cdfabSRobert Mustacchi static size_t smbios_slot_34_contlen = offsetof(smb_slot_cont_t, smbsl_height);
30*d53cdfabSRobert Mustacchi 
31c6795799SRobert Mustacchi static void
smbios_test_slot_fill(smb_slot_t * slot)32c6795799SRobert Mustacchi smbios_test_slot_fill(smb_slot_t *slot)
33c6795799SRobert Mustacchi {
34c6795799SRobert Mustacchi 	bzero(slot, sizeof (smb_slot_t));
35c6795799SRobert Mustacchi 	slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT;
36c6795799SRobert Mustacchi 	slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t);
37c6795799SRobert Mustacchi 	slot->smbsl_name = 1;
38c6795799SRobert Mustacchi 	slot->smbsl_type = SMB_SLT_PCIE3G16;
39c6795799SRobert Mustacchi 	slot->smbsl_width = SMB_SLW_16X;
40c6795799SRobert Mustacchi 	slot->smbsl_length = SMB_SLL_SHORT;
41c6795799SRobert Mustacchi 	slot->smbsl_id = htole16(1);
42c6795799SRobert Mustacchi 	slot->smbsl_ch1 = SMB_SLCH1_33V;
43c6795799SRobert Mustacchi 	slot->smbsl_ch2 = SMB_SLCH2_PME;
44c6795799SRobert Mustacchi 	slot->smbsl_sg = htole16(1);
45c6795799SRobert Mustacchi 	slot->smbsl_bus = smbios_slot_bus;
46c6795799SRobert Mustacchi 	slot->smbsl_df = smbios_slot_df;
47c6795799SRobert Mustacchi 	slot->smbsl_dbw = SMB_SLW_16X;
48c6795799SRobert Mustacchi }
49176a9270SRobert Mustacchi 
50176a9270SRobert Mustacchi boolean_t
smbios_test_slot_mktable(smbios_test_table_t * table)51176a9270SRobert Mustacchi smbios_test_slot_mktable(smbios_test_table_t *table)
52176a9270SRobert Mustacchi {
53176a9270SRobert Mustacchi 	smb_slot_t slot;
54176a9270SRobert Mustacchi 	smb_slot_peer_t peers[2];
55176a9270SRobert Mustacchi 
56c6795799SRobert Mustacchi 	smbios_test_slot_fill(&slot);
57c6795799SRobert Mustacchi 
58c6795799SRobert Mustacchi 	slot.smbsl_hdr.smbh_len += sizeof (peers);
59176a9270SRobert Mustacchi 	slot.smbsl_npeers = 2;
60c6795799SRobert Mustacchi 
61176a9270SRobert Mustacchi 	peers[0].smbspb_group_no = htole16(1);
62176a9270SRobert Mustacchi 	peers[0].smbspb_bus = 0x42;
63176a9270SRobert Mustacchi 	peers[0].smbspb_df = 0x42;
64176a9270SRobert Mustacchi 	peers[0].smbspb_width = SMB_SLW_8X;
65176a9270SRobert Mustacchi 
66176a9270SRobert Mustacchi 	peers[1].smbspb_group_no = htole16(1);
67176a9270SRobert Mustacchi 	peers[1].smbspb_bus = 0x23;
68176a9270SRobert Mustacchi 	peers[1].smbspb_df = 0x31;
69176a9270SRobert Mustacchi 	peers[1].smbspb_width = SMB_SLW_8X;
70176a9270SRobert Mustacchi 
71176a9270SRobert Mustacchi 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
72*d53cdfabSRobert Mustacchi 	smbios_test_table_append_raw(table, peers, sizeof (peers));
73*d53cdfabSRobert Mustacchi 	smbios_test_table_append_string(table, smbios_test_name);
74*d53cdfabSRobert Mustacchi 	smbios_test_table_str_fini(table);
75176a9270SRobert Mustacchi 
76176a9270SRobert Mustacchi 	smbios_test_table_append_eot(table);
77176a9270SRobert Mustacchi 
78176a9270SRobert Mustacchi 	return (B_TRUE);
79176a9270SRobert Mustacchi }
80176a9270SRobert Mustacchi 
81*d53cdfabSRobert Mustacchi static boolean_t
smbios_test_slot_mktable_nopeers(smbios_test_table_t * table,boolean_t is_35)82*d53cdfabSRobert Mustacchi smbios_test_slot_mktable_nopeers(smbios_test_table_t *table, boolean_t is_35)
83c6795799SRobert Mustacchi {
84c6795799SRobert Mustacchi 	smb_slot_t slot;
85c6795799SRobert Mustacchi 	smb_slot_cont_t cont;
86*d53cdfabSRobert Mustacchi 	size_t contlen;
87*d53cdfabSRobert Mustacchi 
88*d53cdfabSRobert Mustacchi 	if (is_35) {
89*d53cdfabSRobert Mustacchi 		contlen = sizeof (cont);
90*d53cdfabSRobert Mustacchi 	} else {
91*d53cdfabSRobert Mustacchi 		contlen = smbios_slot_34_contlen;
92*d53cdfabSRobert Mustacchi 	}
93c6795799SRobert Mustacchi 
94c6795799SRobert Mustacchi 	smbios_test_slot_fill(&slot);
95*d53cdfabSRobert Mustacchi 	slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + contlen;
96c6795799SRobert Mustacchi 
97c6795799SRobert Mustacchi 	cont.smbsl_info = smbios_slot_info;
98c6795799SRobert Mustacchi 	cont.smbsl_pwidth = SMB_SLW_32X;
99c6795799SRobert Mustacchi 	cont.smbsl_pitch = htole16(smbios_slot_pitch);
100*d53cdfabSRobert Mustacchi 	cont.smbsl_height = SMB_SLHT_LP;
101c6795799SRobert Mustacchi 
102c6795799SRobert Mustacchi 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
103*d53cdfabSRobert Mustacchi 	smbios_test_table_append_raw(table, &cont, contlen);
104*d53cdfabSRobert Mustacchi 	smbios_test_table_append_string(table, smbios_test_name);
105*d53cdfabSRobert Mustacchi 	smbios_test_table_str_fini(table);
106c6795799SRobert Mustacchi 	smbios_test_table_append_eot(table);
107*d53cdfabSRobert Mustacchi 
108c6795799SRobert Mustacchi 	return (B_TRUE);
109c6795799SRobert Mustacchi }
110c6795799SRobert Mustacchi 
111*d53cdfabSRobert Mustacchi /*
112*d53cdfabSRobert Mustacchi  * 3.4 introduced additional data after peers. This version constructs a variant
113*d53cdfabSRobert Mustacchi  * with no peers.
114*d53cdfabSRobert Mustacchi  */
115*d53cdfabSRobert Mustacchi boolean_t
smbios_test_slot_mktable_34_nopeers(smbios_test_table_t * table)116*d53cdfabSRobert Mustacchi smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table)
117*d53cdfabSRobert Mustacchi {
118*d53cdfabSRobert Mustacchi 	return (smbios_test_slot_mktable_nopeers(table, B_FALSE));
119*d53cdfabSRobert Mustacchi }
120*d53cdfabSRobert Mustacchi 
121*d53cdfabSRobert Mustacchi boolean_t
smbios_test_slot_mktable_35(smbios_test_table_t * table)122*d53cdfabSRobert Mustacchi smbios_test_slot_mktable_35(smbios_test_table_t *table)
123*d53cdfabSRobert Mustacchi {
124*d53cdfabSRobert Mustacchi 	return (smbios_test_slot_mktable_nopeers(table, B_TRUE));
125*d53cdfabSRobert Mustacchi }
126*d53cdfabSRobert Mustacchi 
127c6795799SRobert Mustacchi boolean_t
smbios_test_slot_mktable_34_peers(smbios_test_table_t * table)128c6795799SRobert Mustacchi smbios_test_slot_mktable_34_peers(smbios_test_table_t *table)
129c6795799SRobert Mustacchi {
130c6795799SRobert Mustacchi 	smb_slot_t slot;
131c6795799SRobert Mustacchi 	smb_slot_cont_t cont;
132c6795799SRobert Mustacchi 	smb_slot_peer_t peers[1];
133c6795799SRobert Mustacchi 
134c6795799SRobert Mustacchi 	smbios_test_slot_fill(&slot);
135c6795799SRobert Mustacchi 	slot.smbsl_npeers = 1;
136c6795799SRobert Mustacchi 	slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers +
137*d53cdfabSRobert Mustacchi 	    smbios_slot_34_contlen;
138c6795799SRobert Mustacchi 
139c6795799SRobert Mustacchi 	peers[0].smbspb_group_no = htole16(1);
140c6795799SRobert Mustacchi 	peers[0].smbspb_bus = 0x42;
141c6795799SRobert Mustacchi 	peers[0].smbspb_df = 0x9a;
142c6795799SRobert Mustacchi 	peers[0].smbspb_width = SMB_SLW_8X;
143c6795799SRobert Mustacchi 
144c6795799SRobert Mustacchi 	cont.smbsl_info = smbios_slot_info;
145c6795799SRobert Mustacchi 	cont.smbsl_pwidth = SMB_SLW_32X;
146c6795799SRobert Mustacchi 	cont.smbsl_pitch = htole16(smbios_slot_pitch);
147c6795799SRobert Mustacchi 
148c6795799SRobert Mustacchi 	(void) smbios_test_table_append(table, &slot, sizeof (slot));
149*d53cdfabSRobert Mustacchi 	smbios_test_table_append_raw(table, peers, sizeof (peers));
150*d53cdfabSRobert Mustacchi 	smbios_test_table_append_raw(table, &cont, smbios_slot_34_contlen);
151*d53cdfabSRobert Mustacchi 	smbios_test_table_append_string(table, smbios_test_name);
152*d53cdfabSRobert Mustacchi 	smbios_test_table_str_fini(table);
153c6795799SRobert Mustacchi 	smbios_test_table_append_eot(table);
154c6795799SRobert Mustacchi 	return (B_TRUE);
155c6795799SRobert Mustacchi }
156c6795799SRobert Mustacchi 
157c6795799SRobert Mustacchi static boolean_t
smbios_test_slot_common(smbios_slot_t * slot)158c6795799SRobert Mustacchi smbios_test_slot_common(smbios_slot_t *slot)
159c6795799SRobert Mustacchi {
160c6795799SRobert Mustacchi 	uint_t errs = 0;
161c6795799SRobert Mustacchi 
162c6795799SRobert Mustacchi 	if (strcmp(slot->smbl_name, smbios_test_name) != 0) {
163c6795799SRobert Mustacchi 		warnx("slot name mismatch, expected %s, found %s",
164c6795799SRobert Mustacchi 		    smbios_test_name, slot->smbl_name);
165c6795799SRobert Mustacchi 		errs++;
166c6795799SRobert Mustacchi 	}
167c6795799SRobert Mustacchi 
168c6795799SRobert Mustacchi 	if (slot->smbl_type != SMB_SLT_PCIE3G16) {
169c6795799SRobert Mustacchi 		warnx("incorrect slot type, found %u", slot->smbl_type);
170c6795799SRobert Mustacchi 		errs++;
171c6795799SRobert Mustacchi 	}
172c6795799SRobert Mustacchi 
173c6795799SRobert Mustacchi 	if (slot->smbl_width != SMB_SLW_16X) {
174c6795799SRobert Mustacchi 		warnx("incorrect slot width, found %u", slot->smbl_width);
175c6795799SRobert Mustacchi 		errs++;
176c6795799SRobert Mustacchi 	}
177c6795799SRobert Mustacchi 
178c6795799SRobert Mustacchi 	if (slot->smbl_length != SMB_SLL_SHORT) {
179c6795799SRobert Mustacchi 		warnx("incorrect slot length, found %u", slot->smbl_length);
180c6795799SRobert Mustacchi 		errs++;
181c6795799SRobert Mustacchi 	}
182c6795799SRobert Mustacchi 
183c6795799SRobert Mustacchi 	if (slot->smbl_dbw != SMB_SLW_16X) {
184c6795799SRobert Mustacchi 		warnx("incorrect slot data bus width, found %u",
185c6795799SRobert Mustacchi 		    slot->smbl_dbw);
186c6795799SRobert Mustacchi 		errs++;
187c6795799SRobert Mustacchi 	}
188c6795799SRobert Mustacchi 
189c6795799SRobert Mustacchi 	if (slot->smbl_bus != smbios_slot_bus) {
190c6795799SRobert Mustacchi 		warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus);
191c6795799SRobert Mustacchi 	}
192c6795799SRobert Mustacchi 
193c6795799SRobert Mustacchi 	if (slot->smbl_df != smbios_slot_df) {
194c6795799SRobert Mustacchi 		warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df);
195c6795799SRobert Mustacchi 	}
196c6795799SRobert Mustacchi 
197c6795799SRobert Mustacchi 	if (errs > 0) {
198c6795799SRobert Mustacchi 		return (B_FALSE);
199c6795799SRobert Mustacchi 	}
200c6795799SRobert Mustacchi 
201c6795799SRobert Mustacchi 	return (B_TRUE);
202c6795799SRobert Mustacchi }
203c6795799SRobert Mustacchi 
204176a9270SRobert Mustacchi boolean_t
smbios_test_slot_verify(smbios_hdl_t * hdl)205176a9270SRobert Mustacchi smbios_test_slot_verify(smbios_hdl_t *hdl)
206176a9270SRobert Mustacchi {
207176a9270SRobert Mustacchi 	smbios_struct_t sp;
208176a9270SRobert Mustacchi 	smbios_slot_t slot;
209176a9270SRobert Mustacchi 	uint_t npeers;
210176a9270SRobert Mustacchi 	smbios_slot_peer_t *peers;
211176a9270SRobert Mustacchi 	uint_t errs = 0;
212176a9270SRobert Mustacchi 
213176a9270SRobert Mustacchi 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
214176a9270SRobert Mustacchi 		warnx("failed to lookup SMBIOS slot: %s",
215176a9270SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
216176a9270SRobert Mustacchi 		return (B_FALSE);
217176a9270SRobert Mustacchi 	}
218176a9270SRobert Mustacchi 
219176a9270SRobert Mustacchi 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
220176a9270SRobert Mustacchi 		warnx("failed to get SMBIOS slot info: %s",
221176a9270SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
222176a9270SRobert Mustacchi 		return (B_FALSE);
223176a9270SRobert Mustacchi 	}
224176a9270SRobert Mustacchi 
225c6795799SRobert Mustacchi 	if (!smbios_test_slot_common(&slot)) {
226176a9270SRobert Mustacchi 		errs++;
227176a9270SRobert Mustacchi 	}
228176a9270SRobert Mustacchi 
229176a9270SRobert Mustacchi 	if (slot.smbl_npeers != 2) {
230176a9270SRobert Mustacchi 		warnx("incorrect number of slot peers, found %u",
231176a9270SRobert Mustacchi 		    slot.smbl_npeers);
232176a9270SRobert Mustacchi 		errs++;
233176a9270SRobert Mustacchi 	}
234176a9270SRobert Mustacchi 
235176a9270SRobert Mustacchi 	if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
236176a9270SRobert Mustacchi 		warnx("failed to get SMBIOS peer info: %s",
237176a9270SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
238176a9270SRobert Mustacchi 		return (B_FALSE);
239176a9270SRobert Mustacchi 	}
240176a9270SRobert Mustacchi 
241176a9270SRobert Mustacchi 	if (npeers != 2) {
242c6795799SRobert Mustacchi 		warnx("got wrong number of slot peers: %u", npeers);
243176a9270SRobert Mustacchi 		return (B_FALSE);
244176a9270SRobert Mustacchi 	}
245176a9270SRobert Mustacchi 
246176a9270SRobert Mustacchi 	if (peers[0].smblp_group != 1) {
247176a9270SRobert Mustacchi 		warnx("incorrect group for peer 0: %u", peers[0].smblp_group);
248176a9270SRobert Mustacchi 		errs++;
249176a9270SRobert Mustacchi 	}
250176a9270SRobert Mustacchi 
251176a9270SRobert Mustacchi 	if (peers[0].smblp_data_width != SMB_SLW_8X) {
252176a9270SRobert Mustacchi 		warnx("incorrect data width for peer 0: %u",
253176a9270SRobert Mustacchi 		    peers[0].smblp_data_width);
254176a9270SRobert Mustacchi 		errs++;
255176a9270SRobert Mustacchi 	}
256176a9270SRobert Mustacchi 
257176a9270SRobert Mustacchi 	if (peers[0].smblp_device != (0x42 >> 3)) {
258176a9270SRobert Mustacchi 		warnx("incorrect PCI device for peer 0: %u",
259176a9270SRobert Mustacchi 		    peers[0].smblp_device);
260176a9270SRobert Mustacchi 		errs++;
261176a9270SRobert Mustacchi 	}
262176a9270SRobert Mustacchi 
263176a9270SRobert Mustacchi 	if (peers[0].smblp_function != (0x42 & 0x7)) {
264176a9270SRobert Mustacchi 		warnx("incorrect PCI function for peer 0: %u",
265176a9270SRobert Mustacchi 		    peers[0].smblp_function);
266176a9270SRobert Mustacchi 		errs++;
267176a9270SRobert Mustacchi 	}
268176a9270SRobert Mustacchi 
269176a9270SRobert Mustacchi 	if (peers[1].smblp_group != 1) {
270176a9270SRobert Mustacchi 		warnx("incorrect group for peer 1: %u", peers[1].smblp_group);
271176a9270SRobert Mustacchi 		errs++;
272176a9270SRobert Mustacchi 	}
273176a9270SRobert Mustacchi 
274176a9270SRobert Mustacchi 	if (peers[1].smblp_device != (0x31 >> 3)) {
275176a9270SRobert Mustacchi 		warnx("incorrect PCI device for peer 1: %u",
276176a9270SRobert Mustacchi 		    peers[1].smblp_device);
277176a9270SRobert Mustacchi 		errs++;
278176a9270SRobert Mustacchi 	}
279176a9270SRobert Mustacchi 
280176a9270SRobert Mustacchi 	if (peers[1].smblp_function != (0x31 & 0x7)) {
281176a9270SRobert Mustacchi 		warnx("incorrect PCI function for peer 1: %u",
282176a9270SRobert Mustacchi 		    peers[1].smblp_function);
283176a9270SRobert Mustacchi 		errs++;
284176a9270SRobert Mustacchi 	}
285176a9270SRobert Mustacchi 
286176a9270SRobert Mustacchi 	if (peers[1].smblp_data_width != SMB_SLW_8X) {
287176a9270SRobert Mustacchi 		warnx("incorrect data width for peer 1: %u",
288176a9270SRobert Mustacchi 		    peers[1].smblp_data_width);
289176a9270SRobert Mustacchi 		errs++;
290176a9270SRobert Mustacchi 	}
291176a9270SRobert Mustacchi 
292176a9270SRobert Mustacchi 	smbios_info_slot_peers_free(hdl, npeers, peers);
293176a9270SRobert Mustacchi 
294c6795799SRobert Mustacchi 	if (slot.smbl_info != 0) {
295c6795799SRobert Mustacchi 		warnx("found wrong slot info: 0x%x", slot.smbl_info);
296c6795799SRobert Mustacchi 		errs++;
297c6795799SRobert Mustacchi 	}
298c6795799SRobert Mustacchi 
299c6795799SRobert Mustacchi 	if (slot.smbl_pwidth != 0) {
300c6795799SRobert Mustacchi 		warnx("found wrong slot physical width: 0x%x",
301c6795799SRobert Mustacchi 		    slot.smbl_pwidth);
302c6795799SRobert Mustacchi 		errs++;
303c6795799SRobert Mustacchi 	}
304c6795799SRobert Mustacchi 
305c6795799SRobert Mustacchi 	if (slot.smbl_pitch != 0) {
306c6795799SRobert Mustacchi 		warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch);
307c6795799SRobert Mustacchi 		errs++;
308c6795799SRobert Mustacchi 	}
309c6795799SRobert Mustacchi 
310c6795799SRobert Mustacchi 	if (errs > 0) {
311c6795799SRobert Mustacchi 		return (B_FALSE);
312c6795799SRobert Mustacchi 	}
313c6795799SRobert Mustacchi 
314c6795799SRobert Mustacchi 	return (B_TRUE);
315c6795799SRobert Mustacchi }
316c6795799SRobert Mustacchi 
317*d53cdfabSRobert Mustacchi static boolean_t
smbios_test_slot_common_nopeers(smbios_hdl_t * hdl,smbios_struct_t * sp,smbios_slot_t * slot)318*d53cdfabSRobert Mustacchi smbios_test_slot_common_nopeers(smbios_hdl_t *hdl, smbios_struct_t *sp,
319*d53cdfabSRobert Mustacchi     smbios_slot_t *slot)
320*d53cdfabSRobert Mustacchi {
321*d53cdfabSRobert Mustacchi 	uint_t errs = 0;
322*d53cdfabSRobert Mustacchi 	uint_t npeers;
323*d53cdfabSRobert Mustacchi 	smbios_slot_peer_t *peers;
324*d53cdfabSRobert Mustacchi 
325*d53cdfabSRobert Mustacchi 	if (slot->smbl_npeers != 0) {
326*d53cdfabSRobert Mustacchi 		warnx("incorrect number of slot peers, found %u",
327*d53cdfabSRobert Mustacchi 		    slot->smbl_npeers);
328*d53cdfabSRobert Mustacchi 		errs++;
329*d53cdfabSRobert Mustacchi 	}
330*d53cdfabSRobert Mustacchi 
331*d53cdfabSRobert Mustacchi 	if (smbios_info_slot_peers(hdl, sp->smbstr_id, &npeers, &peers) != 0) {
332*d53cdfabSRobert Mustacchi 		warnx("failed to get SMBIOS peer info: %s",
333*d53cdfabSRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
334*d53cdfabSRobert Mustacchi 		return (B_FALSE);
335*d53cdfabSRobert Mustacchi 	}
336*d53cdfabSRobert Mustacchi 
337*d53cdfabSRobert Mustacchi 	if (npeers != 0) {
338*d53cdfabSRobert Mustacchi 		warnx("got wrong number of slot peers: %u", npeers);
339*d53cdfabSRobert Mustacchi 		errs++;
340*d53cdfabSRobert Mustacchi 	}
341*d53cdfabSRobert Mustacchi 
342*d53cdfabSRobert Mustacchi 	if (peers != NULL) {
343*d53cdfabSRobert Mustacchi 		warnx("expected NULL peers pointer, but found %p", peers);
344*d53cdfabSRobert Mustacchi 		errs++;
345*d53cdfabSRobert Mustacchi 	}
346*d53cdfabSRobert Mustacchi 
347*d53cdfabSRobert Mustacchi 	smbios_info_slot_peers_free(hdl, npeers, peers);
348*d53cdfabSRobert Mustacchi 
349*d53cdfabSRobert Mustacchi 	if (slot->smbl_info != smbios_slot_info) {
350*d53cdfabSRobert Mustacchi 		warnx("found wrong slot info: 0x%x, expected 0x%x",
351*d53cdfabSRobert Mustacchi 		    slot->smbl_info, smbios_slot_info);
352*d53cdfabSRobert Mustacchi 		errs++;
353*d53cdfabSRobert Mustacchi 	}
354*d53cdfabSRobert Mustacchi 
355*d53cdfabSRobert Mustacchi 	if (slot->smbl_pwidth != SMB_SLW_32X) {
356*d53cdfabSRobert Mustacchi 		warnx("found wrong slot physical width: 0x%x, expected 0x%x",
357*d53cdfabSRobert Mustacchi 		    slot->smbl_pwidth, SMB_SLW_32X);
358*d53cdfabSRobert Mustacchi 		errs++;
359*d53cdfabSRobert Mustacchi 	}
360*d53cdfabSRobert Mustacchi 
361*d53cdfabSRobert Mustacchi 	if (slot->smbl_pitch != smbios_slot_pitch) {
362*d53cdfabSRobert Mustacchi 		warnx("found wrong slot pitch: 0x%x, expected 0x%x",
363*d53cdfabSRobert Mustacchi 		    slot->smbl_pitch, smbios_slot_pitch);
364*d53cdfabSRobert Mustacchi 		errs++;
365*d53cdfabSRobert Mustacchi 	}
366*d53cdfabSRobert Mustacchi 
367*d53cdfabSRobert Mustacchi 	return (errs == 0);
368*d53cdfabSRobert Mustacchi }
369*d53cdfabSRobert Mustacchi 
370c6795799SRobert Mustacchi boolean_t
smbios_test_slot_verify_34_nopeers(smbios_hdl_t * hdl)371c6795799SRobert Mustacchi smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl)
372c6795799SRobert Mustacchi {
373c6795799SRobert Mustacchi 	smbios_struct_t sp;
374c6795799SRobert Mustacchi 	smbios_slot_t slot;
375c6795799SRobert Mustacchi 	uint_t errs = 0;
376c6795799SRobert Mustacchi 
377c6795799SRobert Mustacchi 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
378c6795799SRobert Mustacchi 		warnx("failed to lookup SMBIOS slot: %s",
379c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
380c6795799SRobert Mustacchi 		return (B_FALSE);
381c6795799SRobert Mustacchi 	}
382c6795799SRobert Mustacchi 
383c6795799SRobert Mustacchi 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
384c6795799SRobert Mustacchi 		warnx("failed to get SMBIOS slot info: %s",
385c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
386c6795799SRobert Mustacchi 		return (B_FALSE);
387c6795799SRobert Mustacchi 	}
388c6795799SRobert Mustacchi 
389c6795799SRobert Mustacchi 	if (!smbios_test_slot_common(&slot)) {
390c6795799SRobert Mustacchi 		errs++;
391c6795799SRobert Mustacchi 	}
392c6795799SRobert Mustacchi 
393*d53cdfabSRobert Mustacchi 	if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
394c6795799SRobert Mustacchi 		errs++;
395c6795799SRobert Mustacchi 	}
396c6795799SRobert Mustacchi 
397*d53cdfabSRobert Mustacchi 	if (errs > 0) {
398*d53cdfabSRobert Mustacchi 		return (B_FALSE);
399*d53cdfabSRobert Mustacchi 	}
400*d53cdfabSRobert Mustacchi 
401*d53cdfabSRobert Mustacchi 	return (B_TRUE);
402*d53cdfabSRobert Mustacchi }
403*d53cdfabSRobert Mustacchi 
404*d53cdfabSRobert Mustacchi /*
405*d53cdfabSRobert Mustacchi  * This is a variant of smbios_test_slot_verify_34_nopeers() that specifically
406*d53cdfabSRobert Mustacchi  * uses an older library version and ensures that we don't overrun the
407*d53cdfabSRobert Mustacchi  * smbios_slot_t.
408*d53cdfabSRobert Mustacchi  */
409*d53cdfabSRobert Mustacchi boolean_t
smbios_test_slot_verify_34_overrun(smbios_hdl_t * hdl)410*d53cdfabSRobert Mustacchi smbios_test_slot_verify_34_overrun(smbios_hdl_t *hdl)
411*d53cdfabSRobert Mustacchi {
412*d53cdfabSRobert Mustacchi 	smbios_struct_t sp;
413*d53cdfabSRobert Mustacchi 	smbios_slot_t slot;
414*d53cdfabSRobert Mustacchi 	uint_t errs = 0;
415*d53cdfabSRobert Mustacchi 
416*d53cdfabSRobert Mustacchi 	/*
417*d53cdfabSRobert Mustacchi 	 * We purposefully set the values that are part of SMBIOS 3.5+ to bad
418*d53cdfabSRobert Mustacchi 	 * values to make sure that we don't end up zeroing them.
419*d53cdfabSRobert Mustacchi 	 */
420*d53cdfabSRobert Mustacchi 	slot.smbl_height = 0xba;
421*d53cdfabSRobert Mustacchi 
422*d53cdfabSRobert Mustacchi 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
423*d53cdfabSRobert Mustacchi 		warnx("failed to lookup SMBIOS slot: %s",
424c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
425c6795799SRobert Mustacchi 		return (B_FALSE);
426c6795799SRobert Mustacchi 	}
427c6795799SRobert Mustacchi 
428*d53cdfabSRobert Mustacchi 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
429*d53cdfabSRobert Mustacchi 		warnx("failed to get SMBIOS slot info: %s",
430*d53cdfabSRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
431*d53cdfabSRobert Mustacchi 		return (B_FALSE);
432*d53cdfabSRobert Mustacchi 	}
433*d53cdfabSRobert Mustacchi 
434*d53cdfabSRobert Mustacchi 	if (slot.smbl_height != 0xba) {
435*d53cdfabSRobert Mustacchi 		warnx("smbios 3.4 slot structure was overrun, smbl_height "
436*d53cdfabSRobert Mustacchi 		    "unexpectedly set to 0x%x", slot.smbl_height);
437c6795799SRobert Mustacchi 		errs++;
438c6795799SRobert Mustacchi 	}
439c6795799SRobert Mustacchi 
440*d53cdfabSRobert Mustacchi 	if (!smbios_test_slot_common(&slot)) {
441c6795799SRobert Mustacchi 		errs++;
442c6795799SRobert Mustacchi 	}
443c6795799SRobert Mustacchi 
444*d53cdfabSRobert Mustacchi 	if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
445*d53cdfabSRobert Mustacchi 		errs++;
446*d53cdfabSRobert Mustacchi 	}
447c6795799SRobert Mustacchi 
448*d53cdfabSRobert Mustacchi 	if (errs > 0) {
449*d53cdfabSRobert Mustacchi 		return (B_FALSE);
450*d53cdfabSRobert Mustacchi 	}
451*d53cdfabSRobert Mustacchi 
452*d53cdfabSRobert Mustacchi 	return (B_TRUE);
453*d53cdfabSRobert Mustacchi }
454*d53cdfabSRobert Mustacchi 
455*d53cdfabSRobert Mustacchi boolean_t
smbios_test_slot_verify_35(smbios_hdl_t * hdl)456*d53cdfabSRobert Mustacchi smbios_test_slot_verify_35(smbios_hdl_t *hdl)
457*d53cdfabSRobert Mustacchi {
458*d53cdfabSRobert Mustacchi 	smbios_struct_t sp;
459*d53cdfabSRobert Mustacchi 	smbios_slot_t slot;
460*d53cdfabSRobert Mustacchi 	uint_t errs = 0;
461*d53cdfabSRobert Mustacchi 
462*d53cdfabSRobert Mustacchi 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
463*d53cdfabSRobert Mustacchi 		warnx("failed to lookup SMBIOS slot: %s",
464*d53cdfabSRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
465*d53cdfabSRobert Mustacchi 		return (B_FALSE);
466*d53cdfabSRobert Mustacchi 	}
467*d53cdfabSRobert Mustacchi 
468*d53cdfabSRobert Mustacchi 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
469*d53cdfabSRobert Mustacchi 		warnx("failed to get SMBIOS slot info: %s",
470*d53cdfabSRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
471*d53cdfabSRobert Mustacchi 		return (B_FALSE);
472*d53cdfabSRobert Mustacchi 	}
473*d53cdfabSRobert Mustacchi 
474*d53cdfabSRobert Mustacchi 	if (!smbios_test_slot_common(&slot)) {
475c6795799SRobert Mustacchi 		errs++;
476c6795799SRobert Mustacchi 	}
477c6795799SRobert Mustacchi 
478*d53cdfabSRobert Mustacchi 	if (!smbios_test_slot_common_nopeers(hdl, &sp, &slot)) {
479c6795799SRobert Mustacchi 		errs++;
480c6795799SRobert Mustacchi 	}
481c6795799SRobert Mustacchi 
482*d53cdfabSRobert Mustacchi 	if (slot.smbl_height != SMB_SLHT_LP) {
483*d53cdfabSRobert Mustacchi 		warnx("found wrong slot height: 0x%x, expected 0x%x",
484*d53cdfabSRobert Mustacchi 		    slot.smbl_height, SMB_SLHT_LP);
485c6795799SRobert Mustacchi 		errs++;
486c6795799SRobert Mustacchi 	}
487c6795799SRobert Mustacchi 
488c6795799SRobert Mustacchi 	if (errs > 0) {
489c6795799SRobert Mustacchi 		return (B_FALSE);
490c6795799SRobert Mustacchi 	}
491c6795799SRobert Mustacchi 
492c6795799SRobert Mustacchi 	return (B_TRUE);
493c6795799SRobert Mustacchi }
494c6795799SRobert Mustacchi 
495c6795799SRobert Mustacchi boolean_t
smbios_test_slot_verify_34_peers(smbios_hdl_t * hdl)496c6795799SRobert Mustacchi smbios_test_slot_verify_34_peers(smbios_hdl_t *hdl)
497c6795799SRobert Mustacchi {
498c6795799SRobert Mustacchi 	smbios_struct_t sp;
499c6795799SRobert Mustacchi 	smbios_slot_t slot;
500c6795799SRobert Mustacchi 	uint_t npeers;
501c6795799SRobert Mustacchi 	smbios_slot_peer_t *peers;
502c6795799SRobert Mustacchi 	uint_t errs = 0;
503c6795799SRobert Mustacchi 
504c6795799SRobert Mustacchi 	if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) {
505c6795799SRobert Mustacchi 		warnx("failed to lookup SMBIOS slot: %s",
506c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
507c6795799SRobert Mustacchi 		return (B_FALSE);
508c6795799SRobert Mustacchi 	}
509c6795799SRobert Mustacchi 
510c6795799SRobert Mustacchi 	if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) {
511c6795799SRobert Mustacchi 		warnx("failed to get SMBIOS slot info: %s",
512c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
513c6795799SRobert Mustacchi 		return (B_FALSE);
514c6795799SRobert Mustacchi 	}
515c6795799SRobert Mustacchi 
516c6795799SRobert Mustacchi 	if (!smbios_test_slot_common(&slot)) {
517c6795799SRobert Mustacchi 		errs++;
518c6795799SRobert Mustacchi 	}
519c6795799SRobert Mustacchi 
520c6795799SRobert Mustacchi 	if (slot.smbl_npeers != 1) {
521c6795799SRobert Mustacchi 		warnx("incorrect number of slot peers, found %u",
522c6795799SRobert Mustacchi 		    slot.smbl_npeers);
523c6795799SRobert Mustacchi 		errs++;
524c6795799SRobert Mustacchi 	}
525c6795799SRobert Mustacchi 
526c6795799SRobert Mustacchi 	if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) {
527c6795799SRobert Mustacchi 		warnx("failed to get SMBIOS peer info: %s",
528c6795799SRobert Mustacchi 		    smbios_errmsg(smbios_errno(hdl)));
529c6795799SRobert Mustacchi 		return (B_FALSE);
530c6795799SRobert Mustacchi 	}
531c6795799SRobert Mustacchi 
532c6795799SRobert Mustacchi 	if (npeers != 1) {
533c6795799SRobert Mustacchi 		warnx("got wrong number of slot peers: %u", npeers);
534c6795799SRobert Mustacchi 		errs++;
535c6795799SRobert Mustacchi 	}
536c6795799SRobert Mustacchi 
537c6795799SRobert Mustacchi 	if (peers[0].smblp_group != 1) {
538c6795799SRobert Mustacchi 		warnx("incorrect group for peer 0: %u", peers[0].smblp_group);
539c6795799SRobert Mustacchi 		errs++;
540c6795799SRobert Mustacchi 	}
541c6795799SRobert Mustacchi 
542c6795799SRobert Mustacchi 	if (peers[0].smblp_data_width != SMB_SLW_8X) {
543c6795799SRobert Mustacchi 		warnx("incorrect data width for peer 0: %u",
544c6795799SRobert Mustacchi 		    peers[0].smblp_data_width);
545c6795799SRobert Mustacchi 		errs++;
546c6795799SRobert Mustacchi 	}
547c6795799SRobert Mustacchi 
548c6795799SRobert Mustacchi 	if (peers[0].smblp_bus != 0x42) {
549c6795799SRobert Mustacchi 		warnx("incorrect PCI bus for peer 0: %u",
550c6795799SRobert Mustacchi 		    peers[0].smblp_bus);
551c6795799SRobert Mustacchi 		errs++;
552c6795799SRobert Mustacchi 	}
553c6795799SRobert Mustacchi 
554c6795799SRobert Mustacchi 	if (peers[0].smblp_device != (0x9a >> 3)) {
555c6795799SRobert Mustacchi 		warnx("incorrect PCI device for peer 0: %u",
556c6795799SRobert Mustacchi 		    peers[0].smblp_device);
557c6795799SRobert Mustacchi 		errs++;
558c6795799SRobert Mustacchi 	}
559c6795799SRobert Mustacchi 
560c6795799SRobert Mustacchi 	if (peers[0].smblp_function != (0x9a & 0x7)) {
561c6795799SRobert Mustacchi 		warnx("incorrect PCI function for peer 0: %u",
562c6795799SRobert Mustacchi 		    peers[0].smblp_function);
563c6795799SRobert Mustacchi 		errs++;
564c6795799SRobert Mustacchi 	}
565c6795799SRobert Mustacchi 
566c6795799SRobert Mustacchi 	smbios_info_slot_peers_free(hdl, npeers, peers);
567c6795799SRobert Mustacchi 
568c6795799SRobert Mustacchi 	if (slot.smbl_info != smbios_slot_info) {
569c6795799SRobert Mustacchi 		warnx("found wrong slot info: 0x%x, expected 0x%x",
570c6795799SRobert Mustacchi 		    slot.smbl_info, smbios_slot_info);
571c6795799SRobert Mustacchi 		errs++;
572c6795799SRobert Mustacchi 	}
573c6795799SRobert Mustacchi 
574c6795799SRobert Mustacchi 	if (slot.smbl_pwidth != SMB_SLW_32X) {
575c6795799SRobert Mustacchi 		warnx("found wrong slot physical width: 0x%x, expected 0x%x",
576c6795799SRobert Mustacchi 		    slot.smbl_pwidth, SMB_SLW_32X);
577c6795799SRobert Mustacchi 		errs++;
578c6795799SRobert Mustacchi 	}
579c6795799SRobert Mustacchi 
580c6795799SRobert Mustacchi 	if (slot.smbl_pitch != smbios_slot_pitch) {
581c6795799SRobert Mustacchi 		warnx("found wrong slot pitch: 0x%x, expected 0x%x",
582c6795799SRobert Mustacchi 		    slot.smbl_pitch, smbios_slot_pitch);
583c6795799SRobert Mustacchi 		errs++;
584c6795799SRobert Mustacchi 	}
585c6795799SRobert Mustacchi 
586176a9270SRobert Mustacchi 	if (errs > 0) {
587176a9270SRobert Mustacchi 		return (B_FALSE);
588176a9270SRobert Mustacchi 	}
589176a9270SRobert Mustacchi 
590176a9270SRobert Mustacchi 	return (B_TRUE);
591176a9270SRobert Mustacchi }
592