1 /* 2 * Copyright 2017 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25 #include <ctype.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <stdint.h> 29 #include <string.h> 30 #include <unistd.h> 31 #include <errno.h> 32 33 #include "xf86drm.h" 34 #include "amdgpu_drm.h" 35 #include "amdgpu_internal.h" 36 37 static int parse_one_line(struct amdgpu_device *dev, const char *line) 38 { 39 char *buf, *saveptr; 40 char *s_did; 41 uint32_t did; 42 char *s_rid; 43 uint32_t rid; 44 char *s_name; 45 char *endptr; 46 int r = -EINVAL; 47 48 /* ignore empty line and commented line */ 49 if (strlen(line) == 0 || line[0] == '#') 50 return -EAGAIN; 51 52 buf = strdup(line); 53 if (!buf) 54 return -ENOMEM; 55 56 /* device id */ 57 s_did = strtok_r(buf, ",", &saveptr); 58 if (!s_did) 59 goto out; 60 61 did = strtol(s_did, &endptr, 16); 62 if (*endptr) 63 goto out; 64 65 if (did != dev->info.asic_id) { 66 r = -EAGAIN; 67 goto out; 68 } 69 70 /* revision id */ 71 s_rid = strtok_r(NULL, ",", &saveptr); 72 if (!s_rid) 73 goto out; 74 75 rid = strtol(s_rid, &endptr, 16); 76 if (*endptr) 77 goto out; 78 79 if (rid != dev->info.pci_rev_id) { 80 r = -EAGAIN; 81 goto out; 82 } 83 84 /* marketing name */ 85 s_name = strtok_r(NULL, ",", &saveptr); 86 if (!s_name) 87 goto out; 88 89 /* trim leading whitespaces or tabs */ 90 while (isblank(*s_name)) 91 s_name++; 92 if (strlen(s_name) == 0) 93 goto out; 94 95 dev->marketing_name = strdup(s_name); 96 if (dev->marketing_name) 97 r = 0; 98 else 99 r = -ENOMEM; 100 101 out: 102 free(buf); 103 104 return r; 105 } 106 107 void amdgpu_parse_asic_ids(struct amdgpu_device *dev) 108 { 109 FILE *fp; 110 char *line = NULL; 111 size_t len = 0; 112 ssize_t n; 113 int line_num = 1; 114 int r = 0; 115 116 fp = fopen(AMDGPU_ASIC_ID_TABLE, "r"); 117 if (!fp) { 118 fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE, 119 strerror(errno)); 120 return; 121 } 122 123 /* 1st valid line is file version */ 124 while ((n = getline(&line, &len, fp)) != -1) { 125 /* trim trailing newline */ 126 if (line[n - 1] == '\n') 127 line[n - 1] = '\0'; 128 129 /* ignore empty line and commented line */ 130 if (strlen(line) == 0 || line[0] == '#') { 131 line_num++; 132 continue; 133 } 134 135 drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line); 136 break; 137 } 138 139 while ((n = getline(&line, &len, fp)) != -1) { 140 /* trim trailing newline */ 141 if (line[n - 1] == '\n') 142 line[n - 1] = '\0'; 143 144 r = parse_one_line(dev, line); 145 if (r != -EAGAIN) 146 break; 147 148 line_num++; 149 } 150 151 if (r == -EINVAL) { 152 fprintf(stderr, "Invalid format: %s: line %d: %s\n", 153 AMDGPU_ASIC_ID_TABLE, line_num, line); 154 } else if (r && r != -EAGAIN) { 155 fprintf(stderr, "%s: Cannot parse ASIC IDs: %s\n", 156 __func__, strerror(-r)); 157 } 158 159 free(line); 160 fclose(fp); 161 } 162