View | Details | Raw Unified | Return to bug 272018 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/dev/pci/pci.c (-288 / +263 lines)
Lines 1063-1068 struct vpd_readstate { Link Here
1063
	uint8_t		cksum;
1063
	uint8_t		cksum;
1064
};
1064
};
1065
1065
1066
/* return 0 and one byte in *data if no read error, -1 else */
1066
static int
1067
static int
1067
vpd_nextbyte(struct vpd_readstate *vrs, uint8_t *data)
1068
vpd_nextbyte(struct vpd_readstate *vrs, uint8_t *data)
1068
{
1069
{
Lines 1071-1077 vpd_nextbyte(struct vpd_readstate *vrs, uint8_t *data) Link Here
1071
1072
1072
	if (vrs->bytesinval == 0) {
1073
	if (vrs->bytesinval == 0) {
1073
		if (pci_read_vpd_reg(vrs->pcib, vrs->cfg, vrs->off, &reg))
1074
		if (pci_read_vpd_reg(vrs->pcib, vrs->cfg, vrs->off, &reg))
1074
			return (ENXIO);
1075
			return (-1);
1075
		vrs->val = le32toh(reg);
1076
		vrs->val = le32toh(reg);
1076
		vrs->off += 4;
1077
		vrs->off += 4;
1077
		byte = vrs->val & 0xff;
1078
		byte = vrs->val & 0xff;
Lines 1087-1389 vpd_nextbyte(struct vpd_readstate *vrs, uint8_t *data) Link Here
1087
	return (0);
1088
	return (0);
1088
}
1089
}
1089
1090
1091
/* return 0 on match, -1 and "unget" byte on no match */
1092
static int
1093
vpd_expectbyte(struct vpd_readstate *vrs, uint8_t expected)
1094
{
1095
	uint8_t data;
1096
1097
	if (vpd_nextbyte(vrs, &data) != 0)
1098
		return (-1);
1099
1100
	if (data == expected)
1101
		return (0);
1102
1103
	vrs->cksum -= data;
1104
	vrs->val = (vrs->val << 8) + data;
1105
	vrs->bytesinval++;
1106
	return (-1);
1107
}
1108
1109
/* return size if tag matches, -1 on no match, -2 on read error */
1110
static int
1111
vpd_read_tag_size(struct vpd_readstate *vrs, uint8_t vpd_tag)
1112
{
1113
	uint8_t byte1, byte2;
1114
1115
	if (vpd_expectbyte(vrs, vpd_tag) != 0)
1116
		return (-1);
1117
1118
	if ((vpd_tag & 0x80) == 0)
1119
		return (vpd_tag & 0x07);
1120
1121
	if (vpd_nextbyte(vrs, &byte1) != 0)
1122
		return (-2);
1123
	if (vpd_nextbyte(vrs, &byte2) != 0)
1124
		return (-2);
1125
1126
	return ((byte2 << 8) + byte1);
1127
}
1128
1129
/* (re)allocate buffer in multiples of 8 elements */
1130
static void*
1131
alloc_buffer(void* buffer, size_t element_size, int needed)
1132
{
1133
	int alloc, new_alloc;
1134
1135
	alloc = roundup2(needed, 8);
1136
	new_alloc = roundup2(needed + 1, 8);
1137
	if (alloc != new_alloc) {
1138
		buffer = reallocf(buffer,
1139
		    new_alloc * element_size, M_DEVBUF, M_WAITOK | M_ZERO);
1140
	}
1141
1142
	return (buffer);
1143
}
1144
1145
/* read VPD keyword and return element size, return -1 on read error */
1146
static int
1147
vpd_read_elem_head(struct vpd_readstate *vrs, char keyword[2])
1148
{
1149
	uint8_t data;
1150
1151
	if (vpd_nextbyte(vrs, &keyword[0]) != 0)
1152
		return (-1);
1153
	if (vpd_nextbyte(vrs, &keyword[1]) != 0)
1154
		return (-1);
1155
	if (vpd_nextbyte(vrs, &data) != 0)
1156
		return (-1);
1157
1158
	return (data);
1159
}
1160
1161
/* read VPD data element of given size into allocated buffer */
1162
static char*
1163
vpd_read_value(struct vpd_readstate *vrs, int size)
1164
{
1165
	int i;
1166
	char char1;
1167
	char *value;
1168
1169
	value = malloc(size + 1, M_DEVBUF, M_WAITOK);
1170
	for (i = 0; i < size; i++) {
1171
		if (vpd_nextbyte(vrs, &char1) != 0) {
1172
			free(value, M_DEVBUF);
1173
			return (NULL);
1174
		}
1175
		value[i] = char1;
1176
	}
1177
	value[size] = '\0';
1178
1179
	return (value);
1180
}
1181
1182
/* read VPD into *keyword and *value, return length of data element */
1183
static int
1184
vpd_read_elem_data(struct vpd_readstate *vrs, char keyword[2], char **value, int maxlen)
1185
{
1186
	int len;
1187
1188
	len = vpd_read_elem_head(vrs, keyword);
1189
	if (len > maxlen)
1190
		return (-1);
1191
	*value = vpd_read_value(vrs, len);
1192
1193
	return (len);
1194
}
1195
1196
/* subtract all data following first byte from checksum of RV element */
1090
static void
1197
static void
1091
pci_read_vpd(device_t pcib, pcicfgregs *cfg)
1198
vpd_fixup_cksum(struct vpd_readstate *vrs, char *rvstring, int len)
1092
{
1199
{
1093
	struct vpd_readstate vrs;
1094
	int state;
1095
	int name;
1096
	int remain;
1097
	int i;
1200
	int i;
1098
	int alloc, off;		/* alloc/off for RO/W arrays */
1201
	uint8_t fixup;
1099
	int cksumvalid;
1100
	int dflen;
1101
	int firstrecord;
1102
	uint8_t byte;
1103
	uint8_t byte2;
1104
1202
1105
	/* init vpd reader */
1203
	fixup = 0;
1106
	vrs.bytesinval = 0;
1204
	for (i = 1; i < len; i++)
1107
	vrs.off = 0;
1205
		fixup += rvstring[i];
1108
	vrs.pcib = pcib;
1206
	vrs->cksum -= fixup;
1109
	vrs.cfg = cfg;
1207
}
1110
	vrs.cksum = 0;
1111
1208
1112
	state = 0;
1209
/* fetch one read-only element and return size of heading + data */
1113
	name = remain = i = 0;	/* shut up stupid gcc */
1210
static size_t
1114
	alloc = off = 0;	/* shut up stupid gcc */
1211
next_vpd_ro_elem(struct vpd_readstate *vrs, int maxsize)
1115
	dflen = 0;		/* shut up stupid gcc */
1212
{
1116
	cksumvalid = -1;
1213
	struct pcicfg_vpd *vpd;
1117
	firstrecord = 1;
1214
	pcicfgregs *cfg;
1118
	while (state >= 0) {
1215
	struct vpd_readonly *vpd_ros;
1119
		if (vpd_nextbyte(&vrs, &byte)) {
1216
	int len;
1120
			pci_printf(cfg, "VPD read timed out\n");
1217
1121
			state = -2;
1218
	cfg = vrs->cfg;
1122
			break;
1219
	vpd = &cfg->vpd;
1220
1221
	if (maxsize < 3)
1222
		return (-1);
1223
	vpd->vpd_ros = alloc_buffer(vpd->vpd_ros, sizeof(*vpd->vpd_ros), vpd->vpd_rocnt);
1224
	vpd_ros = &vpd->vpd_ros[vpd->vpd_rocnt];
1225
	maxsize -= 3;
1226
	len = vpd_read_elem_data(vrs, vpd_ros->keyword, &vpd_ros->value, maxsize);
1227
	if (vpd_ros->value == NULL)
1228
		return (-1);
1229
	vpd_ros->len = len;
1230
	if (vpd_ros->keyword[0] == 'R' && vpd_ros->keyword[1] == 'V') {
1231
		vpd_fixup_cksum(vrs, vpd_ros->value, len);
1232
		if (vrs->cksum != 0) {
1233
			pci_printf(cfg,
1234
			    "invalid VPD checksum %#hhx\n", vrs->cksum);
1235
			return (-1);
1123
		}
1236
		}
1124
#if 0
1237
	}
1125
		pci_printf(cfg, "vpd: val: %#x, off: %d, bytesinval: %d, byte: "
1238
	vpd->vpd_rocnt++;
1126
		    "%#hhx, state: %d, remain: %d, name: %#x, i: %d\n", vrs.val,
1127
		    vrs.off, vrs.bytesinval, byte, state, remain, name, i);
1128
#endif
1129
		switch (state) {
1130
		case 0:		/* item name */
1131
			if (byte & 0x80) {
1132
				if (vpd_nextbyte(&vrs, &byte2)) {
1133
					state = -2;
1134
					break;
1135
				}
1136
				remain = byte2;
1137
				if (vpd_nextbyte(&vrs, &byte2)) {
1138
					state = -2;
1139
					break;
1140
				}
1141
				remain |= byte2 << 8;
1142
				name = byte & 0x7f;
1143
			} else {
1144
				remain = byte & 0x7;
1145
				name = (byte >> 3) & 0xf;
1146
			}
1147
			if (firstrecord) {
1148
				if (name != 0x2) {
1149
					pci_printf(cfg, "VPD data does not " \
1150
					    "start with ident (%#x)\n", name);
1151
					state = -2;
1152
					break;
1153
				}
1154
				firstrecord = 0;
1155
			}
1156
			if (vrs.off + remain - vrs.bytesinval > 0x8000) {
1157
				pci_printf(cfg,
1158
				    "VPD data overflow, remain %#x\n", remain);
1159
				state = -1;
1160
				break;
1161
			}
1162
			switch (name) {
1163
			case 0x2:	/* String */
1164
				if (cfg->vpd.vpd_ident != NULL) {
1165
					pci_printf(cfg,
1166
					    "duplicate VPD ident record\n");
1167
					state = -2;
1168
					break;
1169
				}
1170
				if (remain > 255) {
1171
					pci_printf(cfg,
1172
					    "VPD ident length %d exceeds 255\n",
1173
					    remain);
1174
					state = -2;
1175
					break;
1176
				}
1177
				cfg->vpd.vpd_ident = malloc(remain + 1,
1178
				    M_DEVBUF, M_WAITOK);
1179
				i = 0;
1180
				state = 1;
1181
				break;
1182
			case 0xf:	/* End */
1183
				state = -1;
1184
				break;
1185
			case 0x10:	/* VPD-R */
1186
				alloc = 8;
1187
				off = 0;
1188
				cfg->vpd.vpd_ros = malloc(alloc *
1189
				    sizeof(*cfg->vpd.vpd_ros), M_DEVBUF,
1190
				    M_WAITOK | M_ZERO);
1191
				state = 2;
1192
				break;
1193
			case 0x11:	/* VPD-W */
1194
				alloc = 8;
1195
				off = 0;
1196
				cfg->vpd.vpd_w = malloc(alloc *
1197
				    sizeof(*cfg->vpd.vpd_w), M_DEVBUF,
1198
				    M_WAITOK | M_ZERO);
1199
				state = 5;
1200
				break;
1201
			default:	/* Invalid data, abort */
1202
				pci_printf(cfg, "invalid VPD name: %#x\n", name);
1203
				state = -2;
1204
				break;
1205
			}
1206
			break;
1207
1239
1208
		case 1:	/* Identifier String */
1240
	return (len + 3);
1209
			cfg->vpd.vpd_ident[i++] = byte;
1241
}
1210
			remain--;
1211
			if (remain == 0)  {
1212
				cfg->vpd.vpd_ident[i] = '\0';
1213
				state = 0;
1214
			}
1215
			break;
1216
1242
1217
		case 2:	/* VPD-R Keyword Header */
1243
/* fetch one writable element and return size of heading + data */
1218
			if (off == alloc) {
1244
static size_t
1219
				cfg->vpd.vpd_ros = reallocf(cfg->vpd.vpd_ros,
1245
next_vpd_rw_elem(struct vpd_readstate *vrs, int maxsize)
1220
				    (alloc *= 2) * sizeof(*cfg->vpd.vpd_ros),
1246
{
1221
				    M_DEVBUF, M_WAITOK | M_ZERO);
1247
	struct pcicfg_vpd *vpd;
1222
			}
1248
	pcicfgregs *cfg;
1223
			cfg->vpd.vpd_ros[off].keyword[0] = byte;
1249
	struct vpd_write *vpd_w;
1224
			if (vpd_nextbyte(&vrs, &byte2)) {
1250
	int len;
1225
				state = -2;
1226
				break;
1227
			}
1228
			cfg->vpd.vpd_ros[off].keyword[1] = byte2;
1229
			if (vpd_nextbyte(&vrs, &byte2)) {
1230
				state = -2;
1231
				break;
1232
			}
1233
			cfg->vpd.vpd_ros[off].len = dflen = byte2;
1234
			if (dflen == 0 &&
1235
			    strncmp(cfg->vpd.vpd_ros[off].keyword, "RV",
1236
			    2) == 0) {
1237
				/*
1238
				 * if this happens, we can't trust the rest
1239
				 * of the VPD.
1240
				 */
1241
				pci_printf(cfg, "invalid VPD RV record");
1242
				cksumvalid = 0;
1243
				state = -1;
1244
				break;
1245
			} else if (dflen == 0) {
1246
				cfg->vpd.vpd_ros[off].value = malloc(1 *
1247
				    sizeof(*cfg->vpd.vpd_ros[off].value),
1248
				    M_DEVBUF, M_WAITOK);
1249
				cfg->vpd.vpd_ros[off].value[0] = '\x00';
1250
			} else
1251
				cfg->vpd.vpd_ros[off].value = malloc(
1252
				    (dflen + 1) *
1253
				    sizeof(*cfg->vpd.vpd_ros[off].value),
1254
				    M_DEVBUF, M_WAITOK);
1255
			remain -= 3;
1256
			i = 0;
1257
			/* keep in sync w/ state 3's transitions */
1258
			if (dflen == 0 && remain == 0)
1259
				state = 0;
1260
			else if (dflen == 0)
1261
				state = 2;
1262
			else
1263
				state = 3;
1264
			break;
1265
1251
1266
		case 3:	/* VPD-R Keyword Value */
1252
	cfg = vrs->cfg;
1267
			cfg->vpd.vpd_ros[off].value[i++] = byte;
1253
	vpd = &cfg->vpd;
1268
			if (strncmp(cfg->vpd.vpd_ros[off].keyword,
1269
			    "RV", 2) == 0 && cksumvalid == -1) {
1270
				if (vrs.cksum == 0)
1271
					cksumvalid = 1;
1272
				else {
1273
					if (bootverbose)
1274
						pci_printf(cfg,
1275
					    "bad VPD cksum, remain %hhu\n",
1276
						    vrs.cksum);
1277
					cksumvalid = 0;
1278
					state = -1;
1279
					break;
1280
				}
1281
			}
1282
			dflen--;
1283
			remain--;
1284
			/* keep in sync w/ state 2's transitions */
1285
			if (dflen == 0)
1286
				cfg->vpd.vpd_ros[off++].value[i++] = '\0';
1287
			if (dflen == 0 && remain == 0) {
1288
				cfg->vpd.vpd_rocnt = off;
1289
				cfg->vpd.vpd_ros = reallocf(cfg->vpd.vpd_ros,
1290
				    off * sizeof(*cfg->vpd.vpd_ros),
1291
				    M_DEVBUF, M_WAITOK | M_ZERO);
1292
				state = 0;
1293
			} else if (dflen == 0)
1294
				state = 2;
1295
			break;
1296
1254
1297
		case 4:
1255
	if (maxsize < 3)
1298
			remain--;
1256
		return (-1);
1299
			if (remain == 0)
1257
	vpd->vpd_w = alloc_buffer(vpd->vpd_w, sizeof(*vpd->vpd_w), vpd->vpd_wcnt);
1300
				state = 0;
1258
	if (vpd->vpd_w == NULL) {
1301
			break;
1259
		pci_printf(cfg, "out of memory");
1260
		return (-1);
1261
	}
1262
	vpd_w = &vpd->vpd_w[vpd->vpd_wcnt];
1263
	maxsize -= 3;
1264
	vpd_w->start = vrs->off + 3 - vrs->bytesinval;
1265
	len = vpd_read_elem_data(vrs, vpd_w->keyword, &vpd_w->value, maxsize);
1266
	if (vpd_w->value == NULL)
1267
		return (-1);
1268
	vpd_w->len = len;
1269
	vpd->vpd_wcnt++;
1302
1270
1303
		case 5:	/* VPD-W Keyword Header */
1271
	return (len + 3);
1304
			if (off == alloc) {
1272
}
1305
				cfg->vpd.vpd_w = reallocf(cfg->vpd.vpd_w,
1306
				    (alloc *= 2) * sizeof(*cfg->vpd.vpd_w),
1307
				    M_DEVBUF, M_WAITOK | M_ZERO);
1308
			}
1309
			cfg->vpd.vpd_w[off].keyword[0] = byte;
1310
			if (vpd_nextbyte(&vrs, &byte2)) {
1311
				state = -2;
1312
				break;
1313
			}
1314
			cfg->vpd.vpd_w[off].keyword[1] = byte2;
1315
			if (vpd_nextbyte(&vrs, &byte2)) {
1316
				state = -2;
1317
				break;
1318
			}
1319
			cfg->vpd.vpd_w[off].len = dflen = byte2;
1320
			cfg->vpd.vpd_w[off].start = vrs.off - vrs.bytesinval;
1321
			cfg->vpd.vpd_w[off].value = malloc((dflen + 1) *
1322
			    sizeof(*cfg->vpd.vpd_w[off].value),
1323
			    M_DEVBUF, M_WAITOK);
1324
			remain -= 3;
1325
			i = 0;
1326
			/* keep in sync w/ state 6's transitions */
1327
			if (dflen == 0 && remain == 0)
1328
				state = 0;
1329
			else if (dflen == 0)
1330
				state = 5;
1331
			else
1332
				state = 6;
1333
			break;
1334
1273
1335
		case 6:	/* VPD-W Keyword Value */
1274
/* free all memory allocated for VPD data */
1336
			cfg->vpd.vpd_w[off].value[i++] = byte;
1275
static void
1337
			dflen--;
1276
vpd_free(struct pcicfg_vpd *vpd)
1338
			remain--;
1277
{
1339
			/* keep in sync w/ state 5's transitions */
1278
	int i;
1340
			if (dflen == 0)
1341
				cfg->vpd.vpd_w[off++].value[i++] = '\0';
1342
			if (dflen == 0 && remain == 0) {
1343
				cfg->vpd.vpd_wcnt = off;
1344
				cfg->vpd.vpd_w = reallocf(cfg->vpd.vpd_w,
1345
				    off * sizeof(*cfg->vpd.vpd_w),
1346
				    M_DEVBUF, M_WAITOK | M_ZERO);
1347
				state = 0;
1348
			} else if (dflen == 0)
1349
				state = 5;
1350
			break;
1351
1279
1352
		default:
1280
	free(vpd->vpd_ident, M_DEVBUF);
1353
			pci_printf(cfg, "invalid state: %d\n", state);
1281
	for (i = 0; i < vpd->vpd_rocnt; i++)
1354
			state = -1;
1282
		free(vpd->vpd_ros[i].value, M_DEVBUF);
1355
			break;
1283
	free(vpd->vpd_ros, M_DEVBUF);
1356
		}
1284
	vpd->vpd_rocnt = 0;
1285
	for (i = 0; i < vpd->vpd_wcnt; i++)
1286
		free(vpd->vpd_w[i].value, M_DEVBUF);
1287
	free(vpd->vpd_w, M_DEVBUF);
1288
	vpd->vpd_wcnt = 0;
1289
}
1357
1290
1358
		if (cfg->vpd.vpd_ident == NULL || cfg->vpd.vpd_ident[0] == '\0') {
1291
#define VPD_TAG_END	((0x0f << 3) | 0)	/* small tag, len == 0 */
1359
			pci_printf(cfg, "no valid vpd ident found\n");
1292
#define VPD_TAG_IDENT	(0x02 | 0x80)		/* large tag */
1360
			state = -2;
1293
#define VPD_TAG_RO	(0x10 | 0x80)		/* large tag */
1361
		}
1294
#define VPD_TAG_RW	(0x11 | 0x80)		/* large tag */
1295
1296
static int
1297
pci_parse_vpd(device_t pcib, pcicfgregs *cfg)
1298
{
1299
	struct vpd_readstate vrs;
1300
	int cksumvalid;
1301
	int size, elem_size;
1302
1303
	/* init vpd reader */
1304
	vrs.bytesinval = 0;
1305
	vrs.off = 0;
1306
	vrs.pcib = pcib;
1307
	vrs.cfg = cfg;
1308
	vrs.cksum = 0;
1309
1310
	/* read VPD ident element - mandatory */
1311
	size = vpd_read_tag_size(&vrs, VPD_TAG_IDENT);
1312
	if (size <= 0) {
1313
		pci_printf(cfg, "no VPD ident found\n");
1314
		return (0);
1315
	}
1316
	cfg->vpd.vpd_ident = vpd_read_value(&vrs, size);
1317
	if (cfg->vpd.vpd_ident == NULL) {
1318
		pci_printf(cfg, "error accessing VPD ident data\n");
1319
		return (0);
1362
	}
1320
	}
1363
1321
1364
	if (cksumvalid <= 0 || state < -1) {
1322
	/* read VPD RO elements - mandatory */
1365
		/* read-only data bad, clean up */
1323
	size = vpd_read_tag_size(&vrs, VPD_TAG_RO);
1366
		if (cfg->vpd.vpd_ros != NULL) {
1324
	if (size <= 0) {
1367
			for (off = 0; cfg->vpd.vpd_ros[off].value; off++)
1325
		pci_printf(cfg, "no read-only VPD data found\n");
1368
				free(cfg->vpd.vpd_ros[off].value, M_DEVBUF);
1326
		return (0);
1369
			free(cfg->vpd.vpd_ros, M_DEVBUF);
1370
			cfg->vpd.vpd_ros = NULL;
1371
		}
1372
	}
1327
	}
1373
	if (state < -1) {
1328
	while (size > 0) {
1374
		/* I/O error, clean up */
1329
		elem_size = next_vpd_ro_elem(&vrs, size);
1375
		pci_printf(cfg, "failed to read VPD data.\n");
1330
		if (elem_size < 0) {
1376
		if (cfg->vpd.vpd_ident != NULL) {
1331
			pci_printf(cfg, "error accessing read-only VPD data\n");
1377
			free(cfg->vpd.vpd_ident, M_DEVBUF);
1332
			return (-1);
1378
			cfg->vpd.vpd_ident = NULL;
1379
		}
1333
		}
1380
		if (cfg->vpd.vpd_w != NULL) {
1334
		size -= elem_size;
1381
			for (off = 0; cfg->vpd.vpd_w[off].value; off++)
1335
	}
1382
				free(cfg->vpd.vpd_w[off].value, M_DEVBUF);
1336
	cksumvalid = (vrs.cksum == 0);
1383
			free(cfg->vpd.vpd_w, M_DEVBUF);
1337
	if (!cksumvalid)
1384
			cfg->vpd.vpd_w = NULL;
1338
		return (-1);
1339
1340
	/* read VPD RW elements - optional */
1341
	size = vpd_read_tag_size(&vrs, VPD_TAG_RW);
1342
	if (size == -2)
1343
		return (-1);
1344
	while (size > 0) {
1345
		elem_size = next_vpd_rw_elem(&vrs, size);
1346
		if (elem_size < 0) {
1347
			pci_printf(cfg, "error accessing writeable VPD data\n");
1348
			return (-1);
1385
		}
1349
		}
1350
		size -= elem_size;
1351
	}
1352
1353
	/* read empty END tag - mandatory */
1354
	size = vpd_read_tag_size(&vrs, VPD_TAG_END);
1355
	if (size != 0) {
1356
		pci_printf(cfg, "No valid VPD end tag found\n");
1386
	}
1357
	}
1358
	return (0);
1359
}
1360
1361
static void
1362
pci_read_vpd(device_t pcib, pcicfgregs *cfg)
1363
{
1364
	int status;
1365
1366
	status = pci_parse_vpd(pcib, cfg);
1367
	if (status < 0)
1368
		vpd_free(&cfg->vpd);
1387
	cfg->vpd.vpd_cached = 1;
1369
	cfg->vpd.vpd_cached = 1;
1388
#undef REG
1370
#undef REG
1389
#undef WREG
1371
#undef WREG
Lines 2777-2795 pci_freecfg(struct pci_devinfo *dinfo) Link Here
2777
{
2759
{
2778
	struct devlist *devlist_head;
2760
	struct devlist *devlist_head;
2779
	struct pci_map *pm, *next;
2761
	struct pci_map *pm, *next;
2780
	int i;
2781
2762
2782
	devlist_head = &pci_devq;
2763
	devlist_head = &pci_devq;
2783
2764
2784
	if (dinfo->cfg.vpd.vpd_reg) {
2765
	if (dinfo->cfg.vpd.vpd_reg)
2785
		free(dinfo->cfg.vpd.vpd_ident, M_DEVBUF);
2766
		vpd_free(&dinfo->cfg.vpd);
2786
		for (i = 0; i < dinfo->cfg.vpd.vpd_rocnt; i++)
2767
2787
			free(dinfo->cfg.vpd.vpd_ros[i].value, M_DEVBUF);
2788
		free(dinfo->cfg.vpd.vpd_ros, M_DEVBUF);
2789
		for (i = 0; i < dinfo->cfg.vpd.vpd_wcnt; i++)
2790
			free(dinfo->cfg.vpd.vpd_w[i].value, M_DEVBUF);
2791
		free(dinfo->cfg.vpd.vpd_w, M_DEVBUF);
2792
	}
2793
	STAILQ_FOREACH_SAFE(pm, &dinfo->cfg.maps, pm_link, next) {
2768
	STAILQ_FOREACH_SAFE(pm, &dinfo->cfg.maps, pm_link, next) {
2794
		free(pm, M_DEVBUF);
2769
		free(pm, M_DEVBUF);
2795
	}
2770
	}

Return to bug 272018