Home | History | Annotate | Download | only in amdgpu
      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