amdgpu_asic_id.c revision d8807b2f
1d8807b2fSmrg/* 2d8807b2fSmrg * Copyright © 2017 Advanced Micro Devices, Inc. 3d8807b2fSmrg * All Rights Reserved. 4d8807b2fSmrg * 5d8807b2fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 6d8807b2fSmrg * copy of this software and associated documentation files (the "Software"), 7d8807b2fSmrg * to deal in the Software without restriction, including without limitation 8d8807b2fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9d8807b2fSmrg * and/or sell copies of the Software, and to permit persons to whom the 10d8807b2fSmrg * Software is furnished to do so, subject to the following conditions: 11d8807b2fSmrg * 12d8807b2fSmrg * The above copyright notice and this permission notice shall be included in 13d8807b2fSmrg * all copies or substantial portions of the Software. 14d8807b2fSmrg * 15d8807b2fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d8807b2fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d8807b2fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18d8807b2fSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19d8807b2fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20d8807b2fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21d8807b2fSmrg * OTHER DEALINGS IN THE SOFTWARE. 22d8807b2fSmrg * 23d8807b2fSmrg */ 24d8807b2fSmrg 25d8807b2fSmrg#ifdef HAVE_CONFIG_H 26d8807b2fSmrg#include "config.h" 27d8807b2fSmrg#endif 28d8807b2fSmrg 29d8807b2fSmrg#include <ctype.h> 30d8807b2fSmrg#include <stdio.h> 31d8807b2fSmrg#include <stdlib.h> 32d8807b2fSmrg#include <stdint.h> 33d8807b2fSmrg#include <string.h> 34d8807b2fSmrg#include <unistd.h> 35d8807b2fSmrg#include <errno.h> 36d8807b2fSmrg 37d8807b2fSmrg#include "xf86drm.h" 38d8807b2fSmrg#include "amdgpu_drm.h" 39d8807b2fSmrg#include "amdgpu_internal.h" 40d8807b2fSmrg 41d8807b2fSmrgstatic int parse_one_line(const char *line, struct amdgpu_asic_id *id) 42d8807b2fSmrg{ 43d8807b2fSmrg char *buf, *saveptr; 44d8807b2fSmrg char *s_did; 45d8807b2fSmrg char *s_rid; 46d8807b2fSmrg char *s_name; 47d8807b2fSmrg char *endptr; 48d8807b2fSmrg int r = 0; 49d8807b2fSmrg 50d8807b2fSmrg buf = strdup(line); 51d8807b2fSmrg if (!buf) 52d8807b2fSmrg return -ENOMEM; 53d8807b2fSmrg 54d8807b2fSmrg /* ignore empty line and commented line */ 55d8807b2fSmrg if (strlen(line) == 0 || line[0] == '#') { 56d8807b2fSmrg r = -EAGAIN; 57d8807b2fSmrg goto out; 58d8807b2fSmrg } 59d8807b2fSmrg 60d8807b2fSmrg /* device id */ 61d8807b2fSmrg s_did = strtok_r(buf, ",", &saveptr); 62d8807b2fSmrg if (!s_did) { 63d8807b2fSmrg r = -EINVAL; 64d8807b2fSmrg goto out; 65d8807b2fSmrg } 66d8807b2fSmrg 67d8807b2fSmrg id->did = strtol(s_did, &endptr, 16); 68d8807b2fSmrg if (*endptr) { 69d8807b2fSmrg r = -EINVAL; 70d8807b2fSmrg goto out; 71d8807b2fSmrg } 72d8807b2fSmrg 73d8807b2fSmrg /* revision id */ 74d8807b2fSmrg s_rid = strtok_r(NULL, ",", &saveptr); 75d8807b2fSmrg if (!s_rid) { 76d8807b2fSmrg r = -EINVAL; 77d8807b2fSmrg goto out; 78d8807b2fSmrg } 79d8807b2fSmrg 80d8807b2fSmrg id->rid = strtol(s_rid, &endptr, 16); 81d8807b2fSmrg if (*endptr) { 82d8807b2fSmrg r = -EINVAL; 83d8807b2fSmrg goto out; 84d8807b2fSmrg } 85d8807b2fSmrg 86d8807b2fSmrg /* marketing name */ 87d8807b2fSmrg s_name = strtok_r(NULL, ",", &saveptr); 88d8807b2fSmrg if (!s_name) { 89d8807b2fSmrg r = -EINVAL; 90d8807b2fSmrg goto out; 91d8807b2fSmrg } 92d8807b2fSmrg /* trim leading whitespaces or tabs */ 93d8807b2fSmrg while (isblank(*s_name)) 94d8807b2fSmrg s_name++; 95d8807b2fSmrg if (strlen(s_name) == 0) { 96d8807b2fSmrg r = -EINVAL; 97d8807b2fSmrg goto out; 98d8807b2fSmrg } 99d8807b2fSmrg 100d8807b2fSmrg id->marketing_name = strdup(s_name); 101d8807b2fSmrg if (id->marketing_name == NULL) { 102d8807b2fSmrg r = -EINVAL; 103d8807b2fSmrg goto out; 104d8807b2fSmrg } 105d8807b2fSmrg 106d8807b2fSmrgout: 107d8807b2fSmrg free(buf); 108d8807b2fSmrg 109d8807b2fSmrg return r; 110d8807b2fSmrg} 111d8807b2fSmrg 112d8807b2fSmrgint amdgpu_parse_asic_ids(struct amdgpu_asic_id **p_asic_id_table) 113d8807b2fSmrg{ 114d8807b2fSmrg struct amdgpu_asic_id *asic_id_table; 115d8807b2fSmrg struct amdgpu_asic_id *id; 116d8807b2fSmrg FILE *fp; 117d8807b2fSmrg char *line = NULL; 118d8807b2fSmrg size_t len = 0; 119d8807b2fSmrg ssize_t n; 120d8807b2fSmrg int line_num = 1; 121d8807b2fSmrg size_t table_size = 0; 122d8807b2fSmrg size_t table_max_size = AMDGPU_ASIC_ID_TABLE_NUM_ENTRIES; 123d8807b2fSmrg int r = 0; 124d8807b2fSmrg 125d8807b2fSmrg fp = fopen(AMDGPU_ASIC_ID_TABLE, "r"); 126d8807b2fSmrg if (!fp) { 127d8807b2fSmrg fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE, 128d8807b2fSmrg strerror(errno)); 129d8807b2fSmrg return -EINVAL; 130d8807b2fSmrg } 131d8807b2fSmrg 132d8807b2fSmrg asic_id_table = calloc(table_max_size + 1, 133d8807b2fSmrg sizeof(struct amdgpu_asic_id)); 134d8807b2fSmrg if (!asic_id_table) { 135d8807b2fSmrg r = -ENOMEM; 136d8807b2fSmrg goto close; 137d8807b2fSmrg } 138d8807b2fSmrg 139d8807b2fSmrg /* 1st valid line is file version */ 140d8807b2fSmrg while ((n = getline(&line, &len, fp)) != -1) { 141d8807b2fSmrg /* trim trailing newline */ 142d8807b2fSmrg if (line[n - 1] == '\n') 143d8807b2fSmrg line[n - 1] = '\0'; 144d8807b2fSmrg 145d8807b2fSmrg /* ignore empty line and commented line */ 146d8807b2fSmrg if (strlen(line) == 0 || line[0] == '#') { 147d8807b2fSmrg line_num++; 148d8807b2fSmrg continue; 149d8807b2fSmrg } 150d8807b2fSmrg 151d8807b2fSmrg drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line); 152d8807b2fSmrg break; 153d8807b2fSmrg } 154d8807b2fSmrg 155d8807b2fSmrg while ((n = getline(&line, &len, fp)) != -1) { 156d8807b2fSmrg if (table_size > table_max_size) { 157d8807b2fSmrg /* double table size */ 158d8807b2fSmrg table_max_size *= 2; 159d8807b2fSmrg id = realloc(asic_id_table, (table_max_size + 1) * 160d8807b2fSmrg sizeof(struct amdgpu_asic_id)); 161d8807b2fSmrg if (!id) { 162d8807b2fSmrg r = -ENOMEM; 163d8807b2fSmrg goto free; 164d8807b2fSmrg } 165d8807b2fSmrg asic_id_table = id; 166d8807b2fSmrg } 167d8807b2fSmrg 168d8807b2fSmrg id = asic_id_table + table_size; 169d8807b2fSmrg 170d8807b2fSmrg /* trim trailing newline */ 171d8807b2fSmrg if (line[n - 1] == '\n') 172d8807b2fSmrg line[n - 1] = '\0'; 173d8807b2fSmrg 174d8807b2fSmrg r = parse_one_line(line, id); 175d8807b2fSmrg if (r) { 176d8807b2fSmrg if (r == -EAGAIN) { 177d8807b2fSmrg line_num++; 178d8807b2fSmrg continue; 179d8807b2fSmrg } 180d8807b2fSmrg fprintf(stderr, "Invalid format: %s: line %d: %s\n", 181d8807b2fSmrg AMDGPU_ASIC_ID_TABLE, line_num, line); 182d8807b2fSmrg goto free; 183d8807b2fSmrg } 184d8807b2fSmrg 185d8807b2fSmrg line_num++; 186d8807b2fSmrg table_size++; 187d8807b2fSmrg } 188d8807b2fSmrg 189d8807b2fSmrg /* end of table */ 190d8807b2fSmrg id = asic_id_table + table_size; 191d8807b2fSmrg memset(id, 0, sizeof(struct amdgpu_asic_id)); 192d8807b2fSmrg 193d8807b2fSmrg if (table_size != table_max_size) { 194d8807b2fSmrg id = realloc(asic_id_table, (table_size + 1) * 195d8807b2fSmrg sizeof(struct amdgpu_asic_id)); 196d8807b2fSmrg if (!id) 197d8807b2fSmrg r = -ENOMEM; 198d8807b2fSmrg else 199d8807b2fSmrg asic_id_table = id; 200d8807b2fSmrg } 201d8807b2fSmrg 202d8807b2fSmrgfree: 203d8807b2fSmrg free(line); 204d8807b2fSmrg 205d8807b2fSmrg if (r && asic_id_table) { 206d8807b2fSmrg while (table_size--) { 207d8807b2fSmrg id = asic_id_table + table_size; 208d8807b2fSmrg free(id->marketing_name); 209d8807b2fSmrg } 210d8807b2fSmrg free(asic_id_table); 211d8807b2fSmrg asic_id_table = NULL; 212d8807b2fSmrg } 213d8807b2fSmrgclose: 214d8807b2fSmrg fclose(fp); 215d8807b2fSmrg 216d8807b2fSmrg *p_asic_id_table = asic_id_table; 217d8807b2fSmrg 218d8807b2fSmrg return r; 219d8807b2fSmrg} 220