49
49
#define REGISTERS_PATH ((xmlChar*)"./register") /**< all standard registers nodes */
50
50
#define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */
51
51
#define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */
52
#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */
52
#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */
53
53
#define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */
54
54
#define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */
55
55
#define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */
56
#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */
56
#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */
60
59
static const char *pcilib_xml_bank_default_format = "0x%lx";
931
931
err = xmlSchemaSetValidOptions(*validator, XML_SCHEMA_VAL_VC_I_CREATE);
933
933
xmlErrorPtr xmlerr = xmlGetLastError();
934
xmlSchemaFreeValidCtxt(*validator); *validator = NULL;
935
xmlSchemaFree(*schema); *schema = NULL;
934
936
if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message);
935
937
else pcilib_error("Failed to configure the validation context to populate default attributes");
936
938
return PCILIB_ERROR_FAILED;
943
static int pcilib_xml_load_xsd(pcilib_t *ctx, char *model_dir) {
945
static xmlDocPtr pcilib_xml_load_xml_file(pcilib_t *ctx, const char *xsd_filename, const char *xml_filename) {
949
xmlSchemaValidCtxtPtr validator;
950
xmlParserCtxtPtr parser;
952
err = pcilib_xml_load_xsd_file(ctx, xsd_filename, &schema, &validator);
954
pcilib_error("Error (%i) parsing the devices schema (%s)", err, xsd_filename);
958
parser = xmlNewParserCtxt();
960
xmlErrorPtr xmlerr = xmlGetLastError();
961
xmlSchemaFree(schema);
962
xmlSchemaFreeValidCtxt(validator);
963
if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
964
else pcilib_error("Failed to create an XML parser context");
968
doc = xmlCtxtReadFile(parser, xml_filename, NULL, 0);
970
xmlErrorPtr xmlerr = xmlGetLastError();
971
xmlFreeParserCtxt(parser);
972
xmlSchemaFree(schema);
973
xmlSchemaFreeValidCtxt(validator);
974
if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
975
else pcilib_error("Error parsing %s", xml_filename);
979
err = xmlSchemaValidateDoc(validator, doc);
981
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
983
xmlFreeParserCtxt(parser);
984
xmlSchemaFree(schema);
985
xmlSchemaFreeValidCtxt(validator);
986
if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
987
else pcilib_error("Error validating %s", xml_filename);
991
xmlFreeParserCtxt(parser);
992
xmlSchemaFree(schema);
993
xmlSchemaFreeValidCtxt(validator);
999
static xmlXPathObjectPtr pcilib_xml_eval_xpath_expression(pcilib_t *ctx, xmlDocPtr doc, const xmlChar *query) {
1000
xmlXPathContextPtr xpath;
1001
xmlXPathObjectPtr nodes;
1003
xpath = xmlXPathNewContext(doc);
1005
xmlErrorPtr xmlerr = xmlGetLastError();
1006
if (xmlerr) pcilib_error("xmlXpathNewContext reported error %d - %s", xmlerr->code, xmlerr->message);
1007
else pcilib_error("Error creating XPath context");
1011
nodes = xmlXPathEvalExpression(query, xpath);
1013
xmlErrorPtr xmlerr = xmlGetLastError();
1014
xmlXPathFreeContext(xpath);
1015
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", query, xmlerr->code, xmlerr->message);
1016
else pcilib_error("Failed to parse XPath expression %s", query);
1020
xmlXPathFreeContext(xpath);
1024
static int pcilib_xml_load_xsd(pcilib_t *ctx, const char *model_dir) {
983
1064
sprintf(full_name, "%s/%s", path, name);
985
doc = xmlCtxtReadFile(ctx->xml.parser, full_name, NULL, 0);
1066
doc = xmlCtxtReadFile(parser, full_name, NULL, 0);
987
xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
1068
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
988
1069
if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
989
1070
else pcilib_error("Error parsing %s", full_name);
993
err = xmlSchemaValidateDoc(ctx->xml.parts_validator, doc);
1074
err = xmlSchemaValidateDoc(validator, doc);
995
xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
1076
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
996
1077
xmlFreeDoc(doc);
997
1078
if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
998
1079
else pcilib_error("Error validating %s", full_name);
1039
1125
if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
1040
1126
if (file->d_type != DT_REG) continue;
1042
newdoc = pcilib_xml_load_file(ctx, model_path, file->d_name);
1128
newdoc = pcilib_xml_load_model_file(ctx, model_path, file->d_name);
1044
1130
pcilib_error("Error processing XML file %s", file->d_name);
1190
1276
xmlMemoryDump();
1281
char *pcilib_detect_xml_model(pcilib_t *ctx, unsigned int vendor_id, unsigned int device_id) {
1284
xmlSchemaPtr schema; /**< Pointer to the parsed xsd schema */
1285
xmlSchemaValidCtxtPtr validator; /**< Pointer to the XML validation context */
1286
xmlParserCtxtPtr parser; /**< Pointer to the XML parser context */
1289
struct dirent *file = NULL;
1291
const char *data_dir;
1292
char *xsd_path, *xml_path;
1294
xmlXPathObjectPtr nodes;
1295
xmlChar xpath_query[64];
1297
xmlStrPrintf(xpath_query, sizeof(xpath_query), (xmlChar*)"/devices/device[@vendor=%x and @device=%x]/@model", vendor_id, device_id);
1299
data_dir = getenv("PCILIB_DATA_DIR");
1300
if (!data_dir) data_dir = PCILIB_DATA_DIR;
1302
xsd_path = (char*)alloca(strlen(data_dir) + 32);
1303
xml_path = (char*)alloca(strlen(data_dir) + 32);
1304
if ((!xsd_path)||(!xml_path)) {
1305
pcilib_error("Error allocating stack memory");
1309
sprintf(xsd_path, "%s/devices.xsd", data_dir);
1310
sprintf(xml_path, "%s/devices", data_dir);
1311
if (stat(xsd_path, &st)||stat(xml_path, &st)) {
1312
pcilib_info("No XML devices are defined, missing devices schema or list");
1316
parser = xmlNewParserCtxt();
1318
xmlErrorPtr xmlerr = xmlGetLastError();
1319
if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
1320
else pcilib_error("Failed to create an XML parser context");
1324
err = pcilib_xml_load_xsd_file(ctx, xsd_path, &schema, &validator);
1326
xmlFreeParserCtxt(parser);
1327
pcilib_error("Error (%i) parsing the device schema (%s)", err, xsd_path);
1331
rep = opendir(xml_path);
1332
if (!rep) goto cleanup;
1334
while ((model == NULL)&&((file = readdir(rep)) != NULL)) {
1337
size_t len = strlen(file->d_name);
1338
if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
1339
if (file->d_type != DT_REG) continue;
1341
doc = pcilib_xml_load_file(ctx, parser, validator, xml_path, file->d_name);
1344
nodes = pcilib_xml_eval_xpath_expression(ctx, doc, xpath_query);
1350
if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) {
1351
xmlNodePtr node = nodes->nodesetval->nodeTab[0];
1352
model = strdup((char*)node->children->content);
1355
xmlXPathFreeObject(nodes);
1361
xmlSchemaFree(schema);
1362
xmlSchemaFreeValidCtxt(validator);
1363
xmlFreeParserCtxt(parser);