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#include <ctype.h> 26d8807b2fSmrg#include <stdio.h> 27d8807b2fSmrg#include <stdlib.h> 28d8807b2fSmrg#include <stdint.h> 29d8807b2fSmrg#include <string.h> 30d8807b2fSmrg#include <unistd.h> 31d8807b2fSmrg#include <errno.h> 32d8807b2fSmrg 33d8807b2fSmrg#include "xf86drm.h" 34d8807b2fSmrg#include "amdgpu_drm.h" 35d8807b2fSmrg#include "amdgpu_internal.h" 36d8807b2fSmrg 3700a23bdaSmrgstatic int parse_one_line(struct amdgpu_device *dev, const char *line) 38d8807b2fSmrg{ 39d8807b2fSmrg char *buf, *saveptr; 40d8807b2fSmrg char *s_did; 4100a23bdaSmrg uint32_t did; 42d8807b2fSmrg char *s_rid; 4300a23bdaSmrg uint32_t rid; 44d8807b2fSmrg char *s_name; 45d8807b2fSmrg char *endptr; 4600a23bdaSmrg int r = -EINVAL; 4700a23bdaSmrg 4800a23bdaSmrg /* ignore empty line and commented line */ 4900a23bdaSmrg if (strlen(line) == 0 || line[0] == '#') 5000a23bdaSmrg return -EAGAIN; 51d8807b2fSmrg 52d8807b2fSmrg buf = strdup(line); 53d8807b2fSmrg if (!buf) 54d8807b2fSmrg return -ENOMEM; 55d8807b2fSmrg 56d8807b2fSmrg /* device id */ 57d8807b2fSmrg s_did = strtok_r(buf, ",", &saveptr); 5800a23bdaSmrg if (!s_did) 59d8807b2fSmrg goto out; 60d8807b2fSmrg 6100a23bdaSmrg did = strtol(s_did, &endptr, 16); 6200a23bdaSmrg if (*endptr) 6300a23bdaSmrg goto out; 6400a23bdaSmrg 6500a23bdaSmrg if (did != dev->info.asic_id) { 6600a23bdaSmrg r = -EAGAIN; 67d8807b2fSmrg goto out; 68d8807b2fSmrg } 69d8807b2fSmrg 70d8807b2fSmrg /* revision id */ 71d8807b2fSmrg s_rid = strtok_r(NULL, ",", &saveptr); 7200a23bdaSmrg if (!s_rid) 73d8807b2fSmrg goto out; 74d8807b2fSmrg 7500a23bdaSmrg rid = strtol(s_rid, &endptr, 16); 7600a23bdaSmrg if (*endptr) 7700a23bdaSmrg goto out; 7800a23bdaSmrg 7900a23bdaSmrg if (rid != dev->info.pci_rev_id) { 8000a23bdaSmrg r = -EAGAIN; 81d8807b2fSmrg goto out; 82d8807b2fSmrg } 83d8807b2fSmrg 84d8807b2fSmrg /* marketing name */ 85d8807b2fSmrg s_name = strtok_r(NULL, ",", &saveptr); 8600a23bdaSmrg if (!s_name) 87d8807b2fSmrg goto out; 8800a23bdaSmrg 89d8807b2fSmrg /* trim leading whitespaces or tabs */ 90d8807b2fSmrg while (isblank(*s_name)) 91d8807b2fSmrg s_name++; 9200a23bdaSmrg if (strlen(s_name) == 0) 93d8807b2fSmrg goto out; 94d8807b2fSmrg 9500a23bdaSmrg dev->marketing_name = strdup(s_name); 9600a23bdaSmrg if (dev->marketing_name) 9700a23bdaSmrg r = 0; 9800a23bdaSmrg else 9900a23bdaSmrg r = -ENOMEM; 100d8807b2fSmrg 101d8807b2fSmrgout: 102d8807b2fSmrg free(buf); 103d8807b2fSmrg 104d8807b2fSmrg return r; 105d8807b2fSmrg} 106d8807b2fSmrg 10700a23bdaSmrgvoid amdgpu_parse_asic_ids(struct amdgpu_device *dev) 108d8807b2fSmrg{ 109d8807b2fSmrg FILE *fp; 110d8807b2fSmrg char *line = NULL; 111d8807b2fSmrg size_t len = 0; 112d8807b2fSmrg ssize_t n; 113d8807b2fSmrg int line_num = 1; 114d8807b2fSmrg int r = 0; 115d8807b2fSmrg 116d8807b2fSmrg fp = fopen(AMDGPU_ASIC_ID_TABLE, "r"); 117d8807b2fSmrg if (!fp) { 118d8807b2fSmrg fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE, 119d8807b2fSmrg strerror(errno)); 12000a23bdaSmrg return; 121d8807b2fSmrg } 122d8807b2fSmrg 123d8807b2fSmrg /* 1st valid line is file version */ 124d8807b2fSmrg while ((n = getline(&line, &len, fp)) != -1) { 125d8807b2fSmrg /* trim trailing newline */ 126d8807b2fSmrg if (line[n - 1] == '\n') 127d8807b2fSmrg line[n - 1] = '\0'; 128d8807b2fSmrg 129d8807b2fSmrg /* ignore empty line and commented line */ 130d8807b2fSmrg if (strlen(line) == 0 || line[0] == '#') { 131d8807b2fSmrg line_num++; 132d8807b2fSmrg continue; 133d8807b2fSmrg } 134d8807b2fSmrg 135d8807b2fSmrg drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line); 136d8807b2fSmrg break; 137d8807b2fSmrg } 138d8807b2fSmrg 139d8807b2fSmrg while ((n = getline(&line, &len, fp)) != -1) { 140d8807b2fSmrg /* trim trailing newline */ 141d8807b2fSmrg if (line[n - 1] == '\n') 142d8807b2fSmrg line[n - 1] = '\0'; 143d8807b2fSmrg 14400a23bdaSmrg r = parse_one_line(dev, line); 14500a23bdaSmrg if (r != -EAGAIN) 14600a23bdaSmrg break; 147d8807b2fSmrg 148d8807b2fSmrg line_num++; 149d8807b2fSmrg } 150d8807b2fSmrg 15100a23bdaSmrg if (r == -EINVAL) { 15200a23bdaSmrg fprintf(stderr, "Invalid format: %s: line %d: %s\n", 15300a23bdaSmrg AMDGPU_ASIC_ID_TABLE, line_num, line); 15400a23bdaSmrg } else if (r && r != -EAGAIN) { 15500a23bdaSmrg fprintf(stderr, "%s: Cannot parse ASIC IDs: %s\n", 15600a23bdaSmrg __func__, strerror(-r)); 15700a23bdaSmrg } 158d8807b2fSmrg 159d8807b2fSmrg free(line); 160d8807b2fSmrg fclose(fp); 161d8807b2fSmrg} 162