30
30
#include "amdgpu_eeprom.h"
31
31
32
32
#define FRU_EEPROM_MADDR 0x60000
33
- #define I2C_PRODUCT_INFO_OFFSET 0xC0
34
33
35
34
static bool is_fru_eeprom_supported (struct amdgpu_device * adev )
36
35
{
@@ -77,9 +76,10 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
77
76
}
78
77
79
78
static int amdgpu_fru_read_eeprom (struct amdgpu_device * adev , uint32_t addrptr ,
80
- unsigned char * buf )
79
+ unsigned char * buf , size_t buf_size )
81
80
{
82
- int ret , size ;
81
+ int ret ;
82
+ u8 size ;
83
83
84
84
ret = amdgpu_eeprom_read (adev -> pm .fru_eeprom_i2c_bus , addrptr , buf , 1 );
85
85
if (ret < 1 ) {
@@ -90,9 +90,11 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
90
90
/* The size returned by the i2c requires subtraction of 0xC0 since the
91
91
* size apparently always reports as 0xC0+actual size.
92
92
*/
93
- size = buf [0 ] - I2C_PRODUCT_INFO_OFFSET ;
93
+ size = buf [0 ] & 0x3F ;
94
+ size = min_t (size_t , size , buf_size );
94
95
95
- ret = amdgpu_eeprom_read (adev -> pm .fru_eeprom_i2c_bus , addrptr + 1 , buf , size );
96
+ ret = amdgpu_eeprom_read (adev -> pm .fru_eeprom_i2c_bus , addrptr + 1 ,
97
+ buf , size );
96
98
if (ret < 1 ) {
97
99
DRM_WARN ("FRU: Failed to get data field" );
98
100
return ret ;
@@ -129,7 +131,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
129
131
* and the language field, so just start from 0xb, manufacturer size
130
132
*/
131
133
addrptr = FRU_EEPROM_MADDR + 0xb ;
132
- size = amdgpu_fru_read_eeprom (adev , addrptr , buf );
134
+ size = amdgpu_fru_read_eeprom (adev , addrptr , buf , sizeof ( buf ) );
133
135
if (size < 1 ) {
134
136
DRM_ERROR ("Failed to read FRU Manufacturer, ret:%d" , size );
135
137
return - EINVAL ;
@@ -139,7 +141,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
139
141
* size field being 1 byte. This pattern continues below.
140
142
*/
141
143
addrptr += size + 1 ;
142
- size = amdgpu_fru_read_eeprom (adev , addrptr , buf );
144
+ size = amdgpu_fru_read_eeprom (adev , addrptr , buf , sizeof ( buf ) );
143
145
if (size < 1 ) {
144
146
DRM_ERROR ("Failed to read FRU product name, ret:%d" , size );
145
147
return - EINVAL ;
@@ -155,7 +157,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
155
157
adev -> product_name [len ] = '\0' ;
156
158
157
159
addrptr += size + 1 ;
158
- size = amdgpu_fru_read_eeprom (adev , addrptr , buf );
160
+ size = amdgpu_fru_read_eeprom (adev , addrptr , buf , sizeof ( buf ) );
159
161
if (size < 1 ) {
160
162
DRM_ERROR ("Failed to read FRU product number, ret:%d" , size );
161
163
return - EINVAL ;
@@ -173,15 +175,15 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
173
175
adev -> product_number [len ] = '\0' ;
174
176
175
177
addrptr += size + 1 ;
176
- size = amdgpu_fru_read_eeprom (adev , addrptr , buf );
178
+ size = amdgpu_fru_read_eeprom (adev , addrptr , buf , sizeof ( buf ) );
177
179
178
180
if (size < 1 ) {
179
181
DRM_ERROR ("Failed to read FRU product version, ret:%d" , size );
180
182
return - EINVAL ;
181
183
}
182
184
183
185
addrptr += size + 1 ;
184
- size = amdgpu_fru_read_eeprom (adev , addrptr , buf );
186
+ size = amdgpu_fru_read_eeprom (adev , addrptr , buf , sizeof ( buf ) );
185
187
186
188
if (size < 1 ) {
187
189
DRM_ERROR ("Failed to read FRU serial number, ret:%d" , size );
0 commit comments