xref: /openbmc/ipmitool/lib/ipmi_gendev.c (revision c18ec02f)
1*c18ec02fSPetter Reinholdtsen /*
2*c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Kontron Canada, Inc.  All Rights Reserved.
3*c18ec02fSPetter Reinholdtsen  *
4*c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5*c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6*c18ec02fSPetter Reinholdtsen  * are met:
7*c18ec02fSPetter Reinholdtsen  *
8*c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10*c18ec02fSPetter Reinholdtsen  *
11*c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13*c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14*c18ec02fSPetter Reinholdtsen  *
15*c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16*c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17*c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18*c18ec02fSPetter Reinholdtsen  *
19*c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20*c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21*c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22*c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23*c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24*c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25*c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26*c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27*c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28*c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29*c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30*c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31*c18ec02fSPetter Reinholdtsen  */
32*c18ec02fSPetter Reinholdtsen 
33*c18ec02fSPetter Reinholdtsen #include <string.h>
34*c18ec02fSPetter Reinholdtsen 
35*c18ec02fSPetter Reinholdtsen #include <math.h>
36*c18ec02fSPetter Reinholdtsen #include <stdio.h>
37*c18ec02fSPetter Reinholdtsen #include <unistd.h>
38*c18ec02fSPetter Reinholdtsen #include <sys/types.h>
39*c18ec02fSPetter Reinholdtsen #include <time.h>
40*c18ec02fSPetter Reinholdtsen 
41*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
42*c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
43*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
44*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
45*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_gendev.h>
46*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
47*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
48*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_entity.h>
49*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h>
50*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
51*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_raw.h>
52*c18ec02fSPetter Reinholdtsen 
53*c18ec02fSPetter Reinholdtsen #if HAVE_CONFIG_H
54*c18ec02fSPetter Reinholdtsen # include <config.h>
55*c18ec02fSPetter Reinholdtsen #endif
56*c18ec02fSPetter Reinholdtsen 
57*c18ec02fSPetter Reinholdtsen extern int verbose;
58*c18ec02fSPetter Reinholdtsen 
59*c18ec02fSPetter Reinholdtsen 
60*c18ec02fSPetter Reinholdtsen #define GENDEV_RETRY_COUNT    5
61*c18ec02fSPetter Reinholdtsen #define GENDEV_MAX_SIZE       16
62*c18ec02fSPetter Reinholdtsen 
63*c18ec02fSPetter Reinholdtsen typedef struct gendev_eeprom_info
64*c18ec02fSPetter Reinholdtsen {
65*c18ec02fSPetter Reinholdtsen    uint32_t size;
66*c18ec02fSPetter Reinholdtsen    uint16_t page_size;
67*c18ec02fSPetter Reinholdtsen    uint8_t  address_span;
68*c18ec02fSPetter Reinholdtsen    uint8_t  address_length;
69*c18ec02fSPetter Reinholdtsen }t_gendev_eeprom_info;
70*c18ec02fSPetter Reinholdtsen 
71*c18ec02fSPetter Reinholdtsen 
72*c18ec02fSPetter Reinholdtsen static int
ipmi_gendev_get_eeprom_size(struct ipmi_intf * intf,struct sdr_record_generic_locator * dev,t_gendev_eeprom_info * info)73*c18ec02fSPetter Reinholdtsen ipmi_gendev_get_eeprom_size(
74*c18ec02fSPetter Reinholdtsen                         struct ipmi_intf *intf,
75*c18ec02fSPetter Reinholdtsen                         struct sdr_record_generic_locator *dev,
76*c18ec02fSPetter Reinholdtsen                         t_gendev_eeprom_info *info
77*c18ec02fSPetter Reinholdtsen                      )
78*c18ec02fSPetter Reinholdtsen {
79*c18ec02fSPetter Reinholdtsen    int eeprom_size = 0;
80*c18ec02fSPetter Reinholdtsen    /*
81*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Gen Device : %s", dev->id_string);
82*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Access Addr: %x", dev->dev_access_addr);
83*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Slave Addr : %x", dev->dev_slave_addr);
84*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Channel Num: %x", dev->channel_num);
85*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Lun        : %x", dev->lun);
86*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Bus        : %x", dev->bus);
87*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Addr Span  : %x", dev->addr_span);
88*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "DevType    : %x", dev->dev_type);
89*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "DevType Mod: %x", dev->dev_type_modifier);
90*c18ec02fSPetter Reinholdtsen    */
91*c18ec02fSPetter Reinholdtsen    if( info != NULL)
92*c18ec02fSPetter Reinholdtsen    {
93*c18ec02fSPetter Reinholdtsen       switch(dev->dev_type)
94*c18ec02fSPetter Reinholdtsen       {
95*c18ec02fSPetter Reinholdtsen          case 0x08:  // 24C01
96*c18ec02fSPetter Reinholdtsen             info->size = 128;
97*c18ec02fSPetter Reinholdtsen             info->page_size = 8;
98*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
99*c18ec02fSPetter Reinholdtsen             info->address_length = 1;
100*c18ec02fSPetter Reinholdtsen          break;
101*c18ec02fSPetter Reinholdtsen          case 0x09:  // 24C02
102*c18ec02fSPetter Reinholdtsen             info->size = 256;
103*c18ec02fSPetter Reinholdtsen             info->page_size = 8;
104*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
105*c18ec02fSPetter Reinholdtsen             info->address_length = 1;
106*c18ec02fSPetter Reinholdtsen          break;
107*c18ec02fSPetter Reinholdtsen          case 0x0A:  // 24C04
108*c18ec02fSPetter Reinholdtsen             info->size = 512;
109*c18ec02fSPetter Reinholdtsen             info->page_size = 8;
110*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
111*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
112*c18ec02fSPetter Reinholdtsen          break;
113*c18ec02fSPetter Reinholdtsen          case 0x0B:  // 24C08
114*c18ec02fSPetter Reinholdtsen             info->size = 1024;
115*c18ec02fSPetter Reinholdtsen             info->page_size = 8;
116*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
117*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
118*c18ec02fSPetter Reinholdtsen          break;
119*c18ec02fSPetter Reinholdtsen          case 0x0C:  // 24C16
120*c18ec02fSPetter Reinholdtsen             info->size = 2048;
121*c18ec02fSPetter Reinholdtsen             info->page_size = 256;
122*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
123*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
124*c18ec02fSPetter Reinholdtsen          break;
125*c18ec02fSPetter Reinholdtsen          case 0x0D:  // 24C17
126*c18ec02fSPetter Reinholdtsen             info->size = 2048;
127*c18ec02fSPetter Reinholdtsen             info->page_size = 256;
128*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
129*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
130*c18ec02fSPetter Reinholdtsen          break;
131*c18ec02fSPetter Reinholdtsen          case 0x0E:  // 24C32
132*c18ec02fSPetter Reinholdtsen             info->size = 4096;
133*c18ec02fSPetter Reinholdtsen             info->page_size = 8;
134*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
135*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
136*c18ec02fSPetter Reinholdtsen          break;
137*c18ec02fSPetter Reinholdtsen          case 0x0F:  // 24C64
138*c18ec02fSPetter Reinholdtsen             info->size = 8192;
139*c18ec02fSPetter Reinholdtsen             info->page_size = 32;
140*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
141*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
142*c18ec02fSPetter Reinholdtsen          break;
143*c18ec02fSPetter Reinholdtsen          case 0xC0:  // Proposed OEM Code for 24C128
144*c18ec02fSPetter Reinholdtsen             info->size = 16384;
145*c18ec02fSPetter Reinholdtsen             info->page_size = 64;
146*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
147*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
148*c18ec02fSPetter Reinholdtsen          break;
149*c18ec02fSPetter Reinholdtsen          case 0xC1:  // Proposed OEM Code for 24C256
150*c18ec02fSPetter Reinholdtsen             info->size = 32748;
151*c18ec02fSPetter Reinholdtsen             info->page_size = 64;
152*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
153*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
154*c18ec02fSPetter Reinholdtsen          break;
155*c18ec02fSPetter Reinholdtsen          case 0xC2:  // Proposed OEM Code for 24C512
156*c18ec02fSPetter Reinholdtsen             info->size = 65536;
157*c18ec02fSPetter Reinholdtsen             info->page_size = 128;
158*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
159*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
160*c18ec02fSPetter Reinholdtsen          break;
161*c18ec02fSPetter Reinholdtsen          case 0xC3:  // Proposed OEM Code for 24C1024
162*c18ec02fSPetter Reinholdtsen             info->size = 131072;
163*c18ec02fSPetter Reinholdtsen             info->page_size = 128;
164*c18ec02fSPetter Reinholdtsen             info->address_span = dev->addr_span;
165*c18ec02fSPetter Reinholdtsen             info->address_length = 2;
166*c18ec02fSPetter Reinholdtsen          break;
167*c18ec02fSPetter Reinholdtsen          /* Please reserved up to CFh for future update */
168*c18ec02fSPetter Reinholdtsen          default:   // Not a eeprom, return size = 0;
169*c18ec02fSPetter Reinholdtsen             info->size = 0;
170*c18ec02fSPetter Reinholdtsen             info->page_size = 0;
171*c18ec02fSPetter Reinholdtsen             info->address_span = 0;
172*c18ec02fSPetter Reinholdtsen             info->address_length = 0;
173*c18ec02fSPetter Reinholdtsen          break;
174*c18ec02fSPetter Reinholdtsen       }
175*c18ec02fSPetter Reinholdtsen 
176*c18ec02fSPetter Reinholdtsen       eeprom_size = info->size;
177*c18ec02fSPetter Reinholdtsen    }
178*c18ec02fSPetter Reinholdtsen 
179*c18ec02fSPetter Reinholdtsen    return eeprom_size;
180*c18ec02fSPetter Reinholdtsen }
181*c18ec02fSPetter Reinholdtsen 
182*c18ec02fSPetter Reinholdtsen 
183*c18ec02fSPetter Reinholdtsen 
184*c18ec02fSPetter Reinholdtsen static int
ipmi_gendev_read_file(struct ipmi_intf * intf,struct sdr_record_generic_locator * dev,const char * ofile)185*c18ec02fSPetter Reinholdtsen ipmi_gendev_read_file(
186*c18ec02fSPetter Reinholdtsen                         struct ipmi_intf *intf,
187*c18ec02fSPetter Reinholdtsen                         struct sdr_record_generic_locator *dev,
188*c18ec02fSPetter Reinholdtsen                         const char *ofile
189*c18ec02fSPetter Reinholdtsen                      )
190*c18ec02fSPetter Reinholdtsen {
191*c18ec02fSPetter Reinholdtsen    int rc = 0;
192*c18ec02fSPetter Reinholdtsen    int eeprom_size;
193*c18ec02fSPetter Reinholdtsen    t_gendev_eeprom_info eeprom_info;
194*c18ec02fSPetter Reinholdtsen 
195*c18ec02fSPetter Reinholdtsen    eeprom_size = ipmi_gendev_get_eeprom_size(intf, dev, &eeprom_info);
196*c18ec02fSPetter Reinholdtsen 
197*c18ec02fSPetter Reinholdtsen    if(eeprom_size > 0)
198*c18ec02fSPetter Reinholdtsen    {
199*c18ec02fSPetter Reinholdtsen       FILE *fp;
200*c18ec02fSPetter Reinholdtsen 
201*c18ec02fSPetter Reinholdtsen       /* now write to file */
202*c18ec02fSPetter Reinholdtsen       fp = ipmi_open_file_write(ofile);
203*c18ec02fSPetter Reinholdtsen 
204*c18ec02fSPetter Reinholdtsen       if(fp)
205*c18ec02fSPetter Reinholdtsen       {
206*c18ec02fSPetter Reinholdtsen          struct ipmi_rs *rsp;
207*c18ec02fSPetter Reinholdtsen          int numWrite;
208*c18ec02fSPetter Reinholdtsen          uint32_t counter;
209*c18ec02fSPetter Reinholdtsen          uint8_t msize;
210*c18ec02fSPetter Reinholdtsen          uint8_t channel = dev->channel_num;
211*c18ec02fSPetter Reinholdtsen          uint8_t i2cbus = dev->bus;
212*c18ec02fSPetter Reinholdtsen          uint8_t i2caddr = dev->dev_slave_addr;
213*c18ec02fSPetter Reinholdtsen          uint8_t privatebus = 1;
214*c18ec02fSPetter Reinholdtsen          uint32_t address_span_size;
215*c18ec02fSPetter Reinholdtsen          uint8_t percentCompleted = 0;
216*c18ec02fSPetter Reinholdtsen 
217*c18ec02fSPetter Reinholdtsen 
218*c18ec02fSPetter Reinholdtsen          /* Handle Address Span */
219*c18ec02fSPetter Reinholdtsen          if( eeprom_info.address_span != 0)
220*c18ec02fSPetter Reinholdtsen          {
221*c18ec02fSPetter Reinholdtsen             address_span_size =
222*c18ec02fSPetter Reinholdtsen                (eeprom_info.size / (eeprom_info.address_span+1));
223*c18ec02fSPetter Reinholdtsen          }
224*c18ec02fSPetter Reinholdtsen          else
225*c18ec02fSPetter Reinholdtsen          {
226*c18ec02fSPetter Reinholdtsen             address_span_size = eeprom_info.size;
227*c18ec02fSPetter Reinholdtsen          }
228*c18ec02fSPetter Reinholdtsen 
229*c18ec02fSPetter Reinholdtsen          /* Setup read/write size */
230*c18ec02fSPetter Reinholdtsen          if( eeprom_info.page_size < GENDEV_MAX_SIZE)
231*c18ec02fSPetter Reinholdtsen          {
232*c18ec02fSPetter Reinholdtsen             msize = eeprom_info.page_size;
233*c18ec02fSPetter Reinholdtsen          }
234*c18ec02fSPetter Reinholdtsen          else
235*c18ec02fSPetter Reinholdtsen          {
236*c18ec02fSPetter Reinholdtsen             msize = GENDEV_MAX_SIZE;
237*c18ec02fSPetter Reinholdtsen                // All eeprom with page higher than 32 is on the
238*c18ec02fSPetter Reinholdtsen                // 16 bytes boundary
239*c18ec02fSPetter Reinholdtsen          }
240*c18ec02fSPetter Reinholdtsen 
241*c18ec02fSPetter Reinholdtsen          /* Setup i2c bus byte */
242*c18ec02fSPetter Reinholdtsen          i2cbus = ((channel & 0xF) << 4) | ((i2cbus & 7) << 1) | privatebus;
243*c18ec02fSPetter Reinholdtsen 
244*c18ec02fSPetter Reinholdtsen /*
245*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Generic device: %s", dev->id_string);
246*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Chnl: %x", channel);
247*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Bus : %x", i2cbus);
248*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Addr: %x", i2caddr);    */
249*c18ec02fSPetter Reinholdtsen 
250*c18ec02fSPetter Reinholdtsen          for (
251*c18ec02fSPetter Reinholdtsen                counter = 0;
252*c18ec02fSPetter Reinholdtsen                (counter < (eeprom_info.size)) && (rc == 0);
253*c18ec02fSPetter Reinholdtsen                counter+= msize
254*c18ec02fSPetter Reinholdtsen              )
255*c18ec02fSPetter Reinholdtsen          {
256*c18ec02fSPetter Reinholdtsen             uint8_t retryCounter;
257*c18ec02fSPetter Reinholdtsen 
258*c18ec02fSPetter Reinholdtsen             for(
259*c18ec02fSPetter Reinholdtsen                   retryCounter = 0;
260*c18ec02fSPetter Reinholdtsen                   retryCounter<GENDEV_RETRY_COUNT;
261*c18ec02fSPetter Reinholdtsen                   retryCounter ++
262*c18ec02fSPetter Reinholdtsen                )
263*c18ec02fSPetter Reinholdtsen             {
264*c18ec02fSPetter Reinholdtsen                uint8_t wrByte[GENDEV_MAX_SIZE+2];
265*c18ec02fSPetter Reinholdtsen 
266*c18ec02fSPetter Reinholdtsen                wrByte[0] =  (uint8_t) (counter>>0);
267*c18ec02fSPetter Reinholdtsen                if(eeprom_info.address_length > 1)
268*c18ec02fSPetter Reinholdtsen                {
269*c18ec02fSPetter Reinholdtsen                   wrByte[1] =  (uint8_t) (counter>>8);
270*c18ec02fSPetter Reinholdtsen                }
271*c18ec02fSPetter Reinholdtsen 
272*c18ec02fSPetter Reinholdtsen                i2caddr+= (((eeprom_info.size) % address_span_size) * 2);
273*c18ec02fSPetter Reinholdtsen 
274*c18ec02fSPetter Reinholdtsen                rsp = ipmi_master_write_read(
275*c18ec02fSPetter Reinholdtsen                            intf,
276*c18ec02fSPetter Reinholdtsen                            i2cbus,
277*c18ec02fSPetter Reinholdtsen                            i2caddr,
278*c18ec02fSPetter Reinholdtsen                            (uint8_t *) wrByte,
279*c18ec02fSPetter Reinholdtsen                            eeprom_info.address_length,
280*c18ec02fSPetter Reinholdtsen                            msize
281*c18ec02fSPetter Reinholdtsen                            );
282*c18ec02fSPetter Reinholdtsen 
283*c18ec02fSPetter Reinholdtsen                if (rsp != NULL)
284*c18ec02fSPetter Reinholdtsen                {
285*c18ec02fSPetter Reinholdtsen                   retryCounter = GENDEV_RETRY_COUNT;
286*c18ec02fSPetter Reinholdtsen                   rc = 0;
287*c18ec02fSPetter Reinholdtsen                }
288*c18ec02fSPetter Reinholdtsen                else if(retryCounter < GENDEV_RETRY_COUNT)
289*c18ec02fSPetter Reinholdtsen                {
290*c18ec02fSPetter Reinholdtsen                   retryCounter ++;
291*c18ec02fSPetter Reinholdtsen                   lprintf(LOG_ERR, "Retry");
292*c18ec02fSPetter Reinholdtsen                   sleep(1);
293*c18ec02fSPetter Reinholdtsen                   rc = -1;
294*c18ec02fSPetter Reinholdtsen                }
295*c18ec02fSPetter Reinholdtsen                else
296*c18ec02fSPetter Reinholdtsen                {
297*c18ec02fSPetter Reinholdtsen                   lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
298*c18ec02fSPetter Reinholdtsen                   rc = -1;
299*c18ec02fSPetter Reinholdtsen                }
300*c18ec02fSPetter Reinholdtsen             }
301*c18ec02fSPetter Reinholdtsen 
302*c18ec02fSPetter Reinholdtsen             if( rc == 0 )
303*c18ec02fSPetter Reinholdtsen             {
304*c18ec02fSPetter Reinholdtsen                static uint8_t previousCompleted = 101;
305*c18ec02fSPetter Reinholdtsen                numWrite = fwrite(rsp->data, 1, msize, fp);
306*c18ec02fSPetter Reinholdtsen                if (numWrite != msize)
307*c18ec02fSPetter Reinholdtsen                {
308*c18ec02fSPetter Reinholdtsen                   lprintf(LOG_ERR, "Error writing file %s", ofile);
309*c18ec02fSPetter Reinholdtsen                   rc = -1;
310*c18ec02fSPetter Reinholdtsen                   break;
311*c18ec02fSPetter Reinholdtsen                }
312*c18ec02fSPetter Reinholdtsen 
313*c18ec02fSPetter Reinholdtsen                percentCompleted = ((counter * 100) / eeprom_info.size );
314*c18ec02fSPetter Reinholdtsen 
315*c18ec02fSPetter Reinholdtsen                if(percentCompleted != previousCompleted)
316*c18ec02fSPetter Reinholdtsen                {
317*c18ec02fSPetter Reinholdtsen                   printf("\r%i percent completed", percentCompleted);
318*c18ec02fSPetter Reinholdtsen                   previousCompleted = percentCompleted;
319*c18ec02fSPetter Reinholdtsen                }
320*c18ec02fSPetter Reinholdtsen 
321*c18ec02fSPetter Reinholdtsen 
322*c18ec02fSPetter Reinholdtsen             }
323*c18ec02fSPetter Reinholdtsen          }
324*c18ec02fSPetter Reinholdtsen          if(counter == (eeprom_info.size))
325*c18ec02fSPetter Reinholdtsen          {
326*c18ec02fSPetter Reinholdtsen             printf("\r%%100 percent completed\n");
327*c18ec02fSPetter Reinholdtsen          }
328*c18ec02fSPetter Reinholdtsen          else
329*c18ec02fSPetter Reinholdtsen          {
330*c18ec02fSPetter Reinholdtsen             printf("\rError: %i percent completed, read not completed \n", percentCompleted);
331*c18ec02fSPetter Reinholdtsen          }
332*c18ec02fSPetter Reinholdtsen 
333*c18ec02fSPetter Reinholdtsen          fclose(fp);
334*c18ec02fSPetter Reinholdtsen       }
335*c18ec02fSPetter Reinholdtsen    }
336*c18ec02fSPetter Reinholdtsen    else
337*c18ec02fSPetter Reinholdtsen    {
338*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "The selected generic device is not an eeprom");
339*c18ec02fSPetter Reinholdtsen    }
340*c18ec02fSPetter Reinholdtsen 
341*c18ec02fSPetter Reinholdtsen    return rc;
342*c18ec02fSPetter Reinholdtsen }
343*c18ec02fSPetter Reinholdtsen 
344*c18ec02fSPetter Reinholdtsen 
345*c18ec02fSPetter Reinholdtsen /* ipmi_gendev_write_file  -  Read raw SDR from binary file
346*c18ec02fSPetter Reinholdtsen  *
347*c18ec02fSPetter Reinholdtsen  * used for writing generic locator device Eeprom type
348*c18ec02fSPetter Reinholdtsen  *
349*c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
350*c18ec02fSPetter Reinholdtsen  * @dev:		generic device to read
351*c18ec02fSPetter Reinholdtsen  * @ofile:	output filename
352*c18ec02fSPetter Reinholdtsen  *
353*c18ec02fSPetter Reinholdtsen  * returns 0 on success
354*c18ec02fSPetter Reinholdtsen  * returns -1 on error
355*c18ec02fSPetter Reinholdtsen  */
356*c18ec02fSPetter Reinholdtsen static int
ipmi_gendev_write_file(struct ipmi_intf * intf,struct sdr_record_generic_locator * dev,const char * ofile)357*c18ec02fSPetter Reinholdtsen ipmi_gendev_write_file(
358*c18ec02fSPetter Reinholdtsen                         struct ipmi_intf *intf,
359*c18ec02fSPetter Reinholdtsen                         struct sdr_record_generic_locator *dev,
360*c18ec02fSPetter Reinholdtsen                         const char *ofile
361*c18ec02fSPetter Reinholdtsen                      )
362*c18ec02fSPetter Reinholdtsen {
363*c18ec02fSPetter Reinholdtsen    int rc = 0;
364*c18ec02fSPetter Reinholdtsen    int eeprom_size;
365*c18ec02fSPetter Reinholdtsen    t_gendev_eeprom_info eeprom_info;
366*c18ec02fSPetter Reinholdtsen 
367*c18ec02fSPetter Reinholdtsen    eeprom_size = ipmi_gendev_get_eeprom_size(intf, dev, &eeprom_info);
368*c18ec02fSPetter Reinholdtsen 
369*c18ec02fSPetter Reinholdtsen    if(eeprom_size > 0)
370*c18ec02fSPetter Reinholdtsen    {
371*c18ec02fSPetter Reinholdtsen       FILE *fp;
372*c18ec02fSPetter Reinholdtsen       uint32_t fileLength = 0;
373*c18ec02fSPetter Reinholdtsen 
374*c18ec02fSPetter Reinholdtsen       /* now write to file */
375*c18ec02fSPetter Reinholdtsen       fp = ipmi_open_file_read(ofile);
376*c18ec02fSPetter Reinholdtsen 
377*c18ec02fSPetter Reinholdtsen       if(fp)
378*c18ec02fSPetter Reinholdtsen       {
379*c18ec02fSPetter Reinholdtsen          /* Retreive file length, check if it's fits the Eeprom Size */
380*c18ec02fSPetter Reinholdtsen          fseek(fp, 0 ,SEEK_END);
381*c18ec02fSPetter Reinholdtsen          fileLength = ftell(fp);
382*c18ec02fSPetter Reinholdtsen 
383*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "File   Size: %i", fileLength);
384*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Eeprom Size: %i", eeprom_size);
385*c18ec02fSPetter Reinholdtsen          if(fileLength != eeprom_size)
386*c18ec02fSPetter Reinholdtsen          {
387*c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "File size does not fit Eeprom Size");
388*c18ec02fSPetter Reinholdtsen             fclose(fp);
389*c18ec02fSPetter Reinholdtsen             fp = NULL;
390*c18ec02fSPetter Reinholdtsen          }
391*c18ec02fSPetter Reinholdtsen          else
392*c18ec02fSPetter Reinholdtsen          {
393*c18ec02fSPetter Reinholdtsen             fseek(fp, 0 ,SEEK_SET);
394*c18ec02fSPetter Reinholdtsen          }
395*c18ec02fSPetter Reinholdtsen       }
396*c18ec02fSPetter Reinholdtsen 
397*c18ec02fSPetter Reinholdtsen       if(fp)
398*c18ec02fSPetter Reinholdtsen       {
399*c18ec02fSPetter Reinholdtsen          struct ipmi_rs *rsp;
400*c18ec02fSPetter Reinholdtsen          int numRead;
401*c18ec02fSPetter Reinholdtsen          uint32_t counter;
402*c18ec02fSPetter Reinholdtsen          uint8_t msize;
403*c18ec02fSPetter Reinholdtsen          uint8_t channel = dev->channel_num;
404*c18ec02fSPetter Reinholdtsen          uint8_t i2cbus = dev->bus;
405*c18ec02fSPetter Reinholdtsen          uint8_t i2caddr = dev->dev_slave_addr;
406*c18ec02fSPetter Reinholdtsen          uint8_t privatebus = 1;
407*c18ec02fSPetter Reinholdtsen          uint32_t address_span_size;
408*c18ec02fSPetter Reinholdtsen          uint8_t percentCompleted = 0;
409*c18ec02fSPetter Reinholdtsen 
410*c18ec02fSPetter Reinholdtsen 
411*c18ec02fSPetter Reinholdtsen          /* Handle Address Span */
412*c18ec02fSPetter Reinholdtsen          if( eeprom_info.address_span != 0)
413*c18ec02fSPetter Reinholdtsen          {
414*c18ec02fSPetter Reinholdtsen             address_span_size =
415*c18ec02fSPetter Reinholdtsen                (eeprom_info.size / (eeprom_info.address_span+1));
416*c18ec02fSPetter Reinholdtsen          }
417*c18ec02fSPetter Reinholdtsen          else
418*c18ec02fSPetter Reinholdtsen          {
419*c18ec02fSPetter Reinholdtsen             address_span_size = eeprom_info.size;
420*c18ec02fSPetter Reinholdtsen          }
421*c18ec02fSPetter Reinholdtsen 
422*c18ec02fSPetter Reinholdtsen          /* Setup read/write size */
423*c18ec02fSPetter Reinholdtsen          if( eeprom_info.page_size < GENDEV_MAX_SIZE)
424*c18ec02fSPetter Reinholdtsen          {
425*c18ec02fSPetter Reinholdtsen             msize = eeprom_info.page_size;
426*c18ec02fSPetter Reinholdtsen          }
427*c18ec02fSPetter Reinholdtsen          else
428*c18ec02fSPetter Reinholdtsen          {
429*c18ec02fSPetter Reinholdtsen             msize = GENDEV_MAX_SIZE;
430*c18ec02fSPetter Reinholdtsen                      // All eeprom with page higher than 32 is on the
431*c18ec02fSPetter Reinholdtsen                      // 16 bytes boundary
432*c18ec02fSPetter Reinholdtsen          }
433*c18ec02fSPetter Reinholdtsen 
434*c18ec02fSPetter Reinholdtsen          /* Setup i2c bus byte */
435*c18ec02fSPetter Reinholdtsen          i2cbus = ((channel & 0xF) << 4) | ((i2cbus & 7) << 1) | privatebus;
436*c18ec02fSPetter Reinholdtsen 
437*c18ec02fSPetter Reinholdtsen /*
438*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Generic device: %s", dev->id_string);
439*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Chnl: %x", channel);
440*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Bus : %x", i2cbus);
441*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "I2C Addr: %x", i2caddr);    */
442*c18ec02fSPetter Reinholdtsen 
443*c18ec02fSPetter Reinholdtsen          for (
444*c18ec02fSPetter Reinholdtsen                counter = 0;
445*c18ec02fSPetter Reinholdtsen                (counter < (eeprom_info.size)) && (rc == 0);
446*c18ec02fSPetter Reinholdtsen                counter+= msize
447*c18ec02fSPetter Reinholdtsen              )
448*c18ec02fSPetter Reinholdtsen          {
449*c18ec02fSPetter Reinholdtsen             uint8_t retryCounter;
450*c18ec02fSPetter Reinholdtsen             uint8_t readByte[GENDEV_MAX_SIZE];
451*c18ec02fSPetter Reinholdtsen 
452*c18ec02fSPetter Reinholdtsen             numRead = fread(readByte, 1, msize, fp);
453*c18ec02fSPetter Reinholdtsen             if (numRead != msize)
454*c18ec02fSPetter Reinholdtsen             {
455*c18ec02fSPetter Reinholdtsen                lprintf(LOG_ERR, "Error reading file %s", ofile);
456*c18ec02fSPetter Reinholdtsen                rc = -1;
457*c18ec02fSPetter Reinholdtsen                break;
458*c18ec02fSPetter Reinholdtsen             }
459*c18ec02fSPetter Reinholdtsen 
460*c18ec02fSPetter Reinholdtsen 
461*c18ec02fSPetter Reinholdtsen 
462*c18ec02fSPetter Reinholdtsen             for(
463*c18ec02fSPetter Reinholdtsen                   retryCounter = 0;
464*c18ec02fSPetter Reinholdtsen                   retryCounter<GENDEV_RETRY_COUNT;
465*c18ec02fSPetter Reinholdtsen                   retryCounter ++
466*c18ec02fSPetter Reinholdtsen                )
467*c18ec02fSPetter Reinholdtsen             {
468*c18ec02fSPetter Reinholdtsen                uint8_t wrByte[GENDEV_MAX_SIZE+2];
469*c18ec02fSPetter Reinholdtsen                wrByte[0] =  (uint8_t) (counter>>0);
470*c18ec02fSPetter Reinholdtsen                if(eeprom_info.address_length > 1)
471*c18ec02fSPetter Reinholdtsen                {
472*c18ec02fSPetter Reinholdtsen                   wrByte[1] =  (uint8_t) (counter>>8);
473*c18ec02fSPetter Reinholdtsen                }
474*c18ec02fSPetter Reinholdtsen                memcpy(&wrByte[eeprom_info.address_length], readByte, msize);
475*c18ec02fSPetter Reinholdtsen 
476*c18ec02fSPetter Reinholdtsen                i2caddr+= (((eeprom_info.size) % address_span_size) * 2);
477*c18ec02fSPetter Reinholdtsen 
478*c18ec02fSPetter Reinholdtsen                rsp = ipmi_master_write_read(intf, i2cbus, i2caddr, (uint8_t *) wrByte, eeprom_info.address_length+msize, 0);
479*c18ec02fSPetter Reinholdtsen                if (rsp != NULL)
480*c18ec02fSPetter Reinholdtsen                {
481*c18ec02fSPetter Reinholdtsen                   retryCounter = GENDEV_RETRY_COUNT;
482*c18ec02fSPetter Reinholdtsen                   rc = 0;
483*c18ec02fSPetter Reinholdtsen                }
484*c18ec02fSPetter Reinholdtsen                else if(retryCounter < GENDEV_RETRY_COUNT)
485*c18ec02fSPetter Reinholdtsen                {
486*c18ec02fSPetter Reinholdtsen                   retryCounter ++;
487*c18ec02fSPetter Reinholdtsen                   lprintf(LOG_ERR, "Retry");
488*c18ec02fSPetter Reinholdtsen                   sleep(1);
489*c18ec02fSPetter Reinholdtsen                   rc = -1;
490*c18ec02fSPetter Reinholdtsen                }
491*c18ec02fSPetter Reinholdtsen                else
492*c18ec02fSPetter Reinholdtsen                {
493*c18ec02fSPetter Reinholdtsen                   lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
494*c18ec02fSPetter Reinholdtsen                   rc = -1;
495*c18ec02fSPetter Reinholdtsen                }
496*c18ec02fSPetter Reinholdtsen             }
497*c18ec02fSPetter Reinholdtsen 
498*c18ec02fSPetter Reinholdtsen             if( rc == 0 )
499*c18ec02fSPetter Reinholdtsen             {
500*c18ec02fSPetter Reinholdtsen                static uint8_t previousCompleted = 101;
501*c18ec02fSPetter Reinholdtsen                percentCompleted = ((counter * 100) / eeprom_info.size );
502*c18ec02fSPetter Reinholdtsen 
503*c18ec02fSPetter Reinholdtsen                if(percentCompleted != previousCompleted)
504*c18ec02fSPetter Reinholdtsen                {
505*c18ec02fSPetter Reinholdtsen                   printf("\r%i percent completed", percentCompleted);
506*c18ec02fSPetter Reinholdtsen                   previousCompleted = percentCompleted;
507*c18ec02fSPetter Reinholdtsen                }
508*c18ec02fSPetter Reinholdtsen 
509*c18ec02fSPetter Reinholdtsen             }
510*c18ec02fSPetter Reinholdtsen          }
511*c18ec02fSPetter Reinholdtsen          if(counter == (eeprom_info.size))
512*c18ec02fSPetter Reinholdtsen          {
513*c18ec02fSPetter Reinholdtsen             printf("\r%%100 percent completed\n");
514*c18ec02fSPetter Reinholdtsen          }
515*c18ec02fSPetter Reinholdtsen          else
516*c18ec02fSPetter Reinholdtsen          {
517*c18ec02fSPetter Reinholdtsen             printf("\rError: %i percent completed, read not completed \n", percentCompleted);
518*c18ec02fSPetter Reinholdtsen          }
519*c18ec02fSPetter Reinholdtsen 
520*c18ec02fSPetter Reinholdtsen          fclose(fp);
521*c18ec02fSPetter Reinholdtsen       }
522*c18ec02fSPetter Reinholdtsen    }
523*c18ec02fSPetter Reinholdtsen    else
524*c18ec02fSPetter Reinholdtsen    {
525*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "The selected generic device is not an eeprom");
526*c18ec02fSPetter Reinholdtsen    }
527*c18ec02fSPetter Reinholdtsen 
528*c18ec02fSPetter Reinholdtsen    return rc;
529*c18ec02fSPetter Reinholdtsen }
530*c18ec02fSPetter Reinholdtsen 
531*c18ec02fSPetter Reinholdtsen 
532*c18ec02fSPetter Reinholdtsen /* ipmi_gendev_main  -  top-level handler for generic device
533*c18ec02fSPetter Reinholdtsen  *
534*c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
535*c18ec02fSPetter Reinholdtsen  * @argc:	number of arguments
536*c18ec02fSPetter Reinholdtsen  * @argv:	argument list
537*c18ec02fSPetter Reinholdtsen  *
538*c18ec02fSPetter Reinholdtsen  * returns 0 on success
539*c18ec02fSPetter Reinholdtsen  * returns -1 on error
540*c18ec02fSPetter Reinholdtsen  */
541*c18ec02fSPetter Reinholdtsen int
ipmi_gendev_main(struct ipmi_intf * intf,int argc,char ** argv)542*c18ec02fSPetter Reinholdtsen ipmi_gendev_main(struct ipmi_intf *intf, int argc, char **argv)
543*c18ec02fSPetter Reinholdtsen {
544*c18ec02fSPetter Reinholdtsen    int rc = 0;
545*c18ec02fSPetter Reinholdtsen 
546*c18ec02fSPetter Reinholdtsen    /* initialize random numbers used later */
547*c18ec02fSPetter Reinholdtsen    srand(time(NULL));
548*c18ec02fSPetter Reinholdtsen 
549*c18ec02fSPetter Reinholdtsen    lprintf(LOG_ERR, "Rx gendev command: %s", argv[0]);
550*c18ec02fSPetter Reinholdtsen 
551*c18ec02fSPetter Reinholdtsen    if (
552*c18ec02fSPetter Reinholdtsen          (argc == 0)
553*c18ec02fSPetter Reinholdtsen          ||
554*c18ec02fSPetter Reinholdtsen          (strncmp(argv[0], "help", 4) == 0)
555*c18ec02fSPetter Reinholdtsen       )
556*c18ec02fSPetter Reinholdtsen    {
557*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR,
558*c18ec02fSPetter Reinholdtsen          "SDR Commands:  list read write");
559*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR,
560*c18ec02fSPetter Reinholdtsen          "                     list                     List All Generic Device Locators");
561*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR,
562*c18ec02fSPetter Reinholdtsen          "                     read <sdr name> <file>   Read to file eeprom specify by Generic Device Locators");
563*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR,
564*c18ec02fSPetter Reinholdtsen          "                     write <sdr name> <file>  Write from file eeprom specify by Generic Device Locators");
565*c18ec02fSPetter Reinholdtsen    }
566*c18ec02fSPetter Reinholdtsen    else if ( strncmp(argv[0], "list", 4) == 0)
567*c18ec02fSPetter Reinholdtsen    {
568*c18ec02fSPetter Reinholdtsen       rc = ipmi_sdr_print_sdr(intf,
569*c18ec02fSPetter Reinholdtsen                   SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
570*c18ec02fSPetter Reinholdtsen    }
571*c18ec02fSPetter Reinholdtsen    else if (strncmp(argv[0], "read", 4) == 0)
572*c18ec02fSPetter Reinholdtsen    {
573*c18ec02fSPetter Reinholdtsen       if (argc < 3)
574*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "usage: gendev read <gendev> <filename>");
575*c18ec02fSPetter Reinholdtsen       else
576*c18ec02fSPetter Reinholdtsen       {
577*c18ec02fSPetter Reinholdtsen          struct sdr_record_list *sdr;
578*c18ec02fSPetter Reinholdtsen 
579*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Gendev read sdr name : %s", argv[1]);
580*c18ec02fSPetter Reinholdtsen 
581*c18ec02fSPetter Reinholdtsen          printf("Locating sensor record '%s'...\n", argv[1]);
582*c18ec02fSPetter Reinholdtsen 
583*c18ec02fSPetter Reinholdtsen          /* lookup by sensor name */
584*c18ec02fSPetter Reinholdtsen          sdr = ipmi_sdr_find_sdr_byid(intf, argv[1]);
585*c18ec02fSPetter Reinholdtsen          if (sdr == NULL)
586*c18ec02fSPetter Reinholdtsen          {
587*c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "Sensor data record not found!");
588*c18ec02fSPetter Reinholdtsen             return -1;
589*c18ec02fSPetter Reinholdtsen          }
590*c18ec02fSPetter Reinholdtsen 
591*c18ec02fSPetter Reinholdtsen          if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
592*c18ec02fSPetter Reinholdtsen          {
593*c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "Target SDR is not a generic device locator");
594*c18ec02fSPetter Reinholdtsen             return -1;
595*c18ec02fSPetter Reinholdtsen          }
596*c18ec02fSPetter Reinholdtsen 
597*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Gendev read file name: %s", argv[2]);
598*c18ec02fSPetter Reinholdtsen          ipmi_gendev_read_file(intf, sdr->record.genloc, argv[2]);
599*c18ec02fSPetter Reinholdtsen 
600*c18ec02fSPetter Reinholdtsen       }
601*c18ec02fSPetter Reinholdtsen    }
602*c18ec02fSPetter Reinholdtsen    else if (strncmp(argv[0], "write", 5) == 0)
603*c18ec02fSPetter Reinholdtsen    {
604*c18ec02fSPetter Reinholdtsen       if (argc < 3)
605*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "usage: gendev write <gendev> <filename>");
606*c18ec02fSPetter Reinholdtsen       else
607*c18ec02fSPetter Reinholdtsen       {
608*c18ec02fSPetter Reinholdtsen          struct sdr_record_list *sdr;
609*c18ec02fSPetter Reinholdtsen 
610*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Gendev write sdr name : %s", argv[1]);
611*c18ec02fSPetter Reinholdtsen 
612*c18ec02fSPetter Reinholdtsen          printf("Locating sensor record '%s'...\n", argv[1]);
613*c18ec02fSPetter Reinholdtsen 
614*c18ec02fSPetter Reinholdtsen          /* lookup by sensor name */
615*c18ec02fSPetter Reinholdtsen          sdr = ipmi_sdr_find_sdr_byid(intf, argv[1]);
616*c18ec02fSPetter Reinholdtsen          if (sdr == NULL)
617*c18ec02fSPetter Reinholdtsen          {
618*c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "Sensor data record not found!");
619*c18ec02fSPetter Reinholdtsen             return -1;
620*c18ec02fSPetter Reinholdtsen          }
621*c18ec02fSPetter Reinholdtsen 
622*c18ec02fSPetter Reinholdtsen          if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
623*c18ec02fSPetter Reinholdtsen          {
624*c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "Target SDR is not a generic device locator");
625*c18ec02fSPetter Reinholdtsen             return -1;
626*c18ec02fSPetter Reinholdtsen          }
627*c18ec02fSPetter Reinholdtsen 
628*c18ec02fSPetter Reinholdtsen          lprintf(LOG_ERR, "Gendev write file name: %s", argv[2]);
629*c18ec02fSPetter Reinholdtsen          ipmi_gendev_write_file(intf, sdr->record.genloc, argv[2]);
630*c18ec02fSPetter Reinholdtsen 
631*c18ec02fSPetter Reinholdtsen       }
632*c18ec02fSPetter Reinholdtsen    }
633*c18ec02fSPetter Reinholdtsen    else
634*c18ec02fSPetter Reinholdtsen    {
635*c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "Invalid gendev command: %s", argv[0]);
636*c18ec02fSPetter Reinholdtsen       rc = -1;
637*c18ec02fSPetter Reinholdtsen    }
638*c18ec02fSPetter Reinholdtsen 
639*c18ec02fSPetter Reinholdtsen    return rc;
640*c18ec02fSPetter Reinholdtsen }
641