xref: /openbmc/ipmitool/lib/ipmi_sdradd.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
3c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
4c18ec02fSPetter Reinholdtsen  * are met:
5c18ec02fSPetter Reinholdtsen  *
6c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
7c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
8c18ec02fSPetter Reinholdtsen  *
9c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
10c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
11c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
12c18ec02fSPetter Reinholdtsen  *
13c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
14c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
15c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
16c18ec02fSPetter Reinholdtsen  *
17c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
18c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
19c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
20c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
21c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
22c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
23c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
24c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
25c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
26c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
27c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
28c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
29c18ec02fSPetter Reinholdtsen  */
30c18ec02fSPetter Reinholdtsen 
31c18ec02fSPetter Reinholdtsen /*
32c18ec02fSPetter Reinholdtsen  * Functions to program the SDR repository, from built-in sensors or
33c18ec02fSPetter Reinholdtsen  * from sensors dumped in a binary file.
34c18ec02fSPetter Reinholdtsen  */
35c18ec02fSPetter Reinholdtsen 
36c18ec02fSPetter Reinholdtsen #include <stdlib.h>
37c18ec02fSPetter Reinholdtsen #include <string.h>
38c18ec02fSPetter Reinholdtsen #include <stdio.h>
39c18ec02fSPetter Reinholdtsen #include <time.h>
40c18ec02fSPetter Reinholdtsen #include <fcntl.h>
41c18ec02fSPetter Reinholdtsen 
42c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
43c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
47c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
48c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
49c18ec02fSPetter Reinholdtsen 
50c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
51c18ec02fSPetter Reinholdtsen 
52c18ec02fSPetter Reinholdtsen 
53c18ec02fSPetter Reinholdtsen #define ADD_PARTIAL_SDR 0x25
54c18ec02fSPetter Reinholdtsen 
55c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
56c18ec02fSPetter Reinholdtsen #pragma pack(1)
57c18ec02fSPetter Reinholdtsen #endif
58c18ec02fSPetter Reinholdtsen struct sdr_add_rq {
59c18ec02fSPetter Reinholdtsen   uint16_t reserve_id;  /* reservation ID */
60c18ec02fSPetter Reinholdtsen   uint16_t id;          /* record ID */
61c18ec02fSPetter Reinholdtsen   uint8_t offset;       /* offset into SDR */
62c18ec02fSPetter Reinholdtsen   uint8_t in_progress;  /* 0=partial, 1=last */
63c18ec02fSPetter Reinholdtsen #define PARTIAL_ADD (0)
64c18ec02fSPetter Reinholdtsen #define LAST_RECORD (1)
65c18ec02fSPetter Reinholdtsen   uint8_t data[1];      /* SDR record data */
66c18ec02fSPetter Reinholdtsen } ATTRIBUTE_PACKING;
67c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
68c18ec02fSPetter Reinholdtsen #pragma pack(0)
69c18ec02fSPetter Reinholdtsen #endif
70c18ec02fSPetter Reinholdtsen 
71c18ec02fSPetter Reinholdtsen /* This was formerly initialized to 24, reduced this to 19 so the overall
72c18ec02fSPetter Reinholdtsen    message fits into the recommended 32-byte limit */
73c18ec02fSPetter Reinholdtsen static int sdr_max_write_len = 19;
74c18ec02fSPetter Reinholdtsen int ipmi_parse_range_list(const char *rangeList, unsigned char *pHexList);
75c18ec02fSPetter Reinholdtsen int ipmi_hex_to_dec( char * rangeList, unsigned char * pDecValue);
76c18ec02fSPetter Reinholdtsen 
77c18ec02fSPetter Reinholdtsen static int
partial_send(struct ipmi_intf * intf,struct ipmi_rq * req,uint16_t * id)78c18ec02fSPetter Reinholdtsen partial_send(struct ipmi_intf *intf, struct ipmi_rq *req, uint16_t *id)
79c18ec02fSPetter Reinholdtsen {
80c18ec02fSPetter Reinholdtsen   struct ipmi_rs *rsp;
81c18ec02fSPetter Reinholdtsen   rsp = intf->sendrecv(intf, req);
82c18ec02fSPetter Reinholdtsen   if (rsp == NULL) {
83c18ec02fSPetter Reinholdtsen     return -1;
84c18ec02fSPetter Reinholdtsen   }
85c18ec02fSPetter Reinholdtsen 
86c18ec02fSPetter Reinholdtsen   if (rsp->ccode || rsp->data_len < 2) {
87c18ec02fSPetter Reinholdtsen     return -1;
88c18ec02fSPetter Reinholdtsen   }
89c18ec02fSPetter Reinholdtsen 
90c18ec02fSPetter Reinholdtsen   *id = rsp->data[0] + (rsp->data[1] << 8);
91c18ec02fSPetter Reinholdtsen   return 0;
92c18ec02fSPetter Reinholdtsen }
93c18ec02fSPetter Reinholdtsen 
94c18ec02fSPetter Reinholdtsen int
ipmi_sdr_add_record(struct ipmi_intf * intf,struct sdr_record_list * sdrr)95c18ec02fSPetter Reinholdtsen ipmi_sdr_add_record(struct ipmi_intf *intf, struct sdr_record_list *sdrr)
96c18ec02fSPetter Reinholdtsen {
97c18ec02fSPetter Reinholdtsen   struct ipmi_rq req;
98c18ec02fSPetter Reinholdtsen   struct sdr_add_rq *sdr_rq;
99c18ec02fSPetter Reinholdtsen   uint16_t reserve_id;
100c18ec02fSPetter Reinholdtsen   uint16_t id;
101c18ec02fSPetter Reinholdtsen   int i;
102c18ec02fSPetter Reinholdtsen   int len = sdrr->length;
103c18ec02fSPetter Reinholdtsen   int rc = 0;
104c18ec02fSPetter Reinholdtsen 
105c18ec02fSPetter Reinholdtsen   /* actually no SDR to program */
106c18ec02fSPetter Reinholdtsen   if (len < 1 || !sdrr->raw) {
107c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "ipmitool: bad record , skipped");
108c18ec02fSPetter Reinholdtsen     return 0;
109c18ec02fSPetter Reinholdtsen   }
110c18ec02fSPetter Reinholdtsen 
111c18ec02fSPetter Reinholdtsen   if (ipmi_sdr_get_reservation(intf, 0, &reserve_id)) {
112c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "ipmitool: reservation failed");
113c18ec02fSPetter Reinholdtsen     return -1;
114c18ec02fSPetter Reinholdtsen   }
115c18ec02fSPetter Reinholdtsen 
116c18ec02fSPetter Reinholdtsen   sdr_rq = (struct sdr_add_rq *)malloc(sizeof(*sdr_rq) + sdr_max_write_len);
117c18ec02fSPetter Reinholdtsen   if (sdr_rq == NULL) {
118c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "ipmitool: malloc failure");
119c18ec02fSPetter Reinholdtsen     return -1;
120c18ec02fSPetter Reinholdtsen   }
121c18ec02fSPetter Reinholdtsen   sdr_rq->reserve_id = reserve_id;
122c18ec02fSPetter Reinholdtsen   sdr_rq->in_progress = PARTIAL_ADD;
123c18ec02fSPetter Reinholdtsen 
124c18ec02fSPetter Reinholdtsen   memset(&req, 0, sizeof(req));
125c18ec02fSPetter Reinholdtsen   req.msg.netfn = IPMI_NETFN_STORAGE;
126c18ec02fSPetter Reinholdtsen   req.msg.cmd = ADD_PARTIAL_SDR;
127c18ec02fSPetter Reinholdtsen   req.msg.data = (uint8_t *) sdr_rq;
128c18ec02fSPetter Reinholdtsen 
129c18ec02fSPetter Reinholdtsen   /* header first */
130c18ec02fSPetter Reinholdtsen   sdr_rq->id = 0;
131c18ec02fSPetter Reinholdtsen   sdr_rq->offset = 0;
132c18ec02fSPetter Reinholdtsen   sdr_rq->data[0] = sdrr->id & 0xFF;
133c18ec02fSPetter Reinholdtsen   sdr_rq->data[1] = (sdrr->id >> 8) & 0xFF;
134c18ec02fSPetter Reinholdtsen   sdr_rq->data[2] = sdrr->version;
135c18ec02fSPetter Reinholdtsen   sdr_rq->data[3] = sdrr->type;
136c18ec02fSPetter Reinholdtsen   sdr_rq->data[4] = sdrr->length;
137c18ec02fSPetter Reinholdtsen   req.msg.data_len = 5 + sizeof(*sdr_rq) - 1;
138c18ec02fSPetter Reinholdtsen 
139c18ec02fSPetter Reinholdtsen   if (partial_send(intf, &req, &id)) {
140c18ec02fSPetter Reinholdtsen      lprintf(LOG_ERR, "ipmitool: partial send error");
141c18ec02fSPetter Reinholdtsen     free(sdr_rq);
142c18ec02fSPetter Reinholdtsen     sdr_rq = NULL;
143c18ec02fSPetter Reinholdtsen     return -1;
144c18ec02fSPetter Reinholdtsen   }
145c18ec02fSPetter Reinholdtsen 
146c18ec02fSPetter Reinholdtsen   i = 0;
147c18ec02fSPetter Reinholdtsen 
148c18ec02fSPetter Reinholdtsen   /* sdr entry */
149c18ec02fSPetter Reinholdtsen   while (i < len) {
150c18ec02fSPetter Reinholdtsen      int data_len = 0;
151c18ec02fSPetter Reinholdtsen      if ( (len - i) <= sdr_max_write_len) {
152c18ec02fSPetter Reinholdtsen       /* last crunch */
153c18ec02fSPetter Reinholdtsen       data_len = len - i;
154c18ec02fSPetter Reinholdtsen       sdr_rq->in_progress = LAST_RECORD;
155c18ec02fSPetter Reinholdtsen     } else {
156c18ec02fSPetter Reinholdtsen       data_len = sdr_max_write_len;
157c18ec02fSPetter Reinholdtsen     }
158c18ec02fSPetter Reinholdtsen 
159c18ec02fSPetter Reinholdtsen     sdr_rq->id = id;
160c18ec02fSPetter Reinholdtsen     sdr_rq->offset = i + 5;
161c18ec02fSPetter Reinholdtsen     memcpy(sdr_rq->data, sdrr->raw + i, data_len);
162c18ec02fSPetter Reinholdtsen     req.msg.data_len = data_len + sizeof(*sdr_rq) - 1;
163c18ec02fSPetter Reinholdtsen 
164c18ec02fSPetter Reinholdtsen     if ((rc = partial_send(intf, &req, &id)) != 0) {
165c18ec02fSPetter Reinholdtsen        lprintf(LOG_ERR, "ipmitool: partial add failed");
166c18ec02fSPetter Reinholdtsen       break;
167c18ec02fSPetter Reinholdtsen     }
168c18ec02fSPetter Reinholdtsen 
169c18ec02fSPetter Reinholdtsen     i += data_len;
170c18ec02fSPetter Reinholdtsen   }
171c18ec02fSPetter Reinholdtsen 
172c18ec02fSPetter Reinholdtsen   free(sdr_rq);
173c18ec02fSPetter Reinholdtsen   sdr_rq = NULL;
174c18ec02fSPetter Reinholdtsen   return rc;
175c18ec02fSPetter Reinholdtsen }
176c18ec02fSPetter Reinholdtsen 
177c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_repo_clear(struct ipmi_intf * intf)178c18ec02fSPetter Reinholdtsen ipmi_sdr_repo_clear(struct ipmi_intf *intf)
179c18ec02fSPetter Reinholdtsen {
180c18ec02fSPetter Reinholdtsen   struct ipmi_rs * rsp;
181c18ec02fSPetter Reinholdtsen   struct ipmi_rq req;
182c18ec02fSPetter Reinholdtsen   uint8_t msg_data[8];
183c18ec02fSPetter Reinholdtsen   uint16_t reserve_id;
184c18ec02fSPetter Reinholdtsen   int try;
185c18ec02fSPetter Reinholdtsen 
186c18ec02fSPetter Reinholdtsen   if (ipmi_sdr_get_reservation(intf, 0, &reserve_id))
187c18ec02fSPetter Reinholdtsen     return -1;
188c18ec02fSPetter Reinholdtsen 
189c18ec02fSPetter Reinholdtsen   memset(&req, 0, sizeof(req));
190c18ec02fSPetter Reinholdtsen   req.msg.netfn = IPMI_NETFN_STORAGE;
191c18ec02fSPetter Reinholdtsen   req.msg.cmd = 0x27; // FIXME
192c18ec02fSPetter Reinholdtsen   req.msg.data = msg_data;
193c18ec02fSPetter Reinholdtsen   req.msg.data_len = 6;
194c18ec02fSPetter Reinholdtsen 
195c18ec02fSPetter Reinholdtsen   msg_data[0] = reserve_id & 0xFF;
196c18ec02fSPetter Reinholdtsen   msg_data[1] = reserve_id >> 8;
197c18ec02fSPetter Reinholdtsen   msg_data[2] = 'C';
198c18ec02fSPetter Reinholdtsen   msg_data[3] = 'L';
199c18ec02fSPetter Reinholdtsen   msg_data[4] = 'R';
200c18ec02fSPetter Reinholdtsen   msg_data[5] = 0xAA;
201c18ec02fSPetter Reinholdtsen 
202c18ec02fSPetter Reinholdtsen   for (try = 0; try < 5; try++) {
203c18ec02fSPetter Reinholdtsen     rsp = intf->sendrecv(intf, &req);
204c18ec02fSPetter Reinholdtsen     if (rsp == NULL) {
205c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "Unable to clear SDRR");
206c18ec02fSPetter Reinholdtsen       return -1;
207c18ec02fSPetter Reinholdtsen     }
208c18ec02fSPetter Reinholdtsen     if (rsp->ccode > 0) {
209c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "Unable to clear SDRR: %s",
210c18ec02fSPetter Reinholdtsen         val2str(rsp->ccode, completion_code_vals));
211c18ec02fSPetter Reinholdtsen       return -1;
212c18ec02fSPetter Reinholdtsen     }
213c18ec02fSPetter Reinholdtsen     if ((rsp->data[0] & 1) == 1) {
214c18ec02fSPetter Reinholdtsen       printf("SDRR successfully erased\n");
215c18ec02fSPetter Reinholdtsen       return 0;
216c18ec02fSPetter Reinholdtsen     }
217c18ec02fSPetter Reinholdtsen     printf("Wait for SDRR erasure completed...\n");
218c18ec02fSPetter Reinholdtsen     msg_data[5] = 0;
219c18ec02fSPetter Reinholdtsen     sleep(1);
220c18ec02fSPetter Reinholdtsen   }
221c18ec02fSPetter Reinholdtsen 
222c18ec02fSPetter Reinholdtsen   /* if we are here we fed up trying erase */
223c18ec02fSPetter Reinholdtsen   return -1;
224c18ec02fSPetter Reinholdtsen }
225c18ec02fSPetter Reinholdtsen 
226c18ec02fSPetter Reinholdtsen 
227c18ec02fSPetter Reinholdtsen struct sdrr_queue {
228c18ec02fSPetter Reinholdtsen   struct sdr_record_list *head;
229c18ec02fSPetter Reinholdtsen   struct sdr_record_list *tail;
230c18ec02fSPetter Reinholdtsen };
231c18ec02fSPetter Reinholdtsen 
232c18ec02fSPetter Reinholdtsen 
233c18ec02fSPetter Reinholdtsen /*
234c18ec02fSPetter Reinholdtsen  * Fill the SDR repository from built-in sensors
235c18ec02fSPetter Reinholdtsen  *
236c18ec02fSPetter Reinholdtsen  */
237c18ec02fSPetter Reinholdtsen 
238c18ec02fSPetter Reinholdtsen /*
239c18ec02fSPetter Reinholdtsen  * Get all the SDR records stored in <queue>
240c18ec02fSPetter Reinholdtsen  */
241c18ec02fSPetter Reinholdtsen static int
sdrr_get_records(struct ipmi_intf * intf,struct ipmi_sdr_iterator * itr,struct sdrr_queue * queue)242c18ec02fSPetter Reinholdtsen sdrr_get_records(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr,
243c18ec02fSPetter Reinholdtsen                  struct sdrr_queue *queue)
244c18ec02fSPetter Reinholdtsen {
245c18ec02fSPetter Reinholdtsen   struct sdr_get_rs *header;
246c18ec02fSPetter Reinholdtsen 
247c18ec02fSPetter Reinholdtsen   queue->head = NULL;
248c18ec02fSPetter Reinholdtsen   queue->tail = NULL;
249c18ec02fSPetter Reinholdtsen 
250c18ec02fSPetter Reinholdtsen   while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
251c18ec02fSPetter Reinholdtsen     struct sdr_record_list *sdrr;
252c18ec02fSPetter Reinholdtsen 
253c18ec02fSPetter Reinholdtsen     sdrr = malloc(sizeof (struct sdr_record_list));
254c18ec02fSPetter Reinholdtsen     if (sdrr == NULL) {
255c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "ipmitool: malloc failure");
256c18ec02fSPetter Reinholdtsen       return -1;
257c18ec02fSPetter Reinholdtsen     }
258c18ec02fSPetter Reinholdtsen     memset(sdrr, 0, sizeof (struct sdr_record_list));
259c18ec02fSPetter Reinholdtsen 
260c18ec02fSPetter Reinholdtsen     sdrr->id = header->id;
261c18ec02fSPetter Reinholdtsen     sdrr->version = header->version;
262c18ec02fSPetter Reinholdtsen     sdrr->type = header->type;
263c18ec02fSPetter Reinholdtsen     sdrr->length = header->length;
264c18ec02fSPetter Reinholdtsen     sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
265c18ec02fSPetter Reinholdtsen     (void)ipmi_sdr_print_name_from_rawentry(intf,  sdrr->id, sdrr->type,sdrr->raw);
266c18ec02fSPetter Reinholdtsen 
267c18ec02fSPetter Reinholdtsen     /* put in the record queue */
268c18ec02fSPetter Reinholdtsen     if (queue->head == NULL)
269c18ec02fSPetter Reinholdtsen       queue->head = sdrr;
270c18ec02fSPetter Reinholdtsen     else
271c18ec02fSPetter Reinholdtsen       queue->tail->next = sdrr;
272c18ec02fSPetter Reinholdtsen     queue->tail = sdrr;
273c18ec02fSPetter Reinholdtsen   }
274c18ec02fSPetter Reinholdtsen   return 0;
275c18ec02fSPetter Reinholdtsen }
276c18ec02fSPetter Reinholdtsen 
277c18ec02fSPetter Reinholdtsen static int
sdr_copy_to_sdrr(struct ipmi_intf * intf,int use_builtin,int from_addr,int to_addr)278c18ec02fSPetter Reinholdtsen sdr_copy_to_sdrr(struct ipmi_intf *intf, int use_builtin,
279c18ec02fSPetter Reinholdtsen                  int from_addr, int to_addr)
280c18ec02fSPetter Reinholdtsen {
281c18ec02fSPetter Reinholdtsen   int rc;
282c18ec02fSPetter Reinholdtsen   struct sdrr_queue sdrr_queue;
283c18ec02fSPetter Reinholdtsen   struct ipmi_sdr_iterator *itr;
284c18ec02fSPetter Reinholdtsen   struct sdr_record_list *sdrr;
285c18ec02fSPetter Reinholdtsen   struct sdr_record_list *sdrr_next;
286c18ec02fSPetter Reinholdtsen 
287c18ec02fSPetter Reinholdtsen   /* generate list of records for this target */
288c18ec02fSPetter Reinholdtsen   intf->target_addr = from_addr;
289c18ec02fSPetter Reinholdtsen 
290c18ec02fSPetter Reinholdtsen   /* initialize iterator */
291c18ec02fSPetter Reinholdtsen   itr = ipmi_sdr_start(intf, use_builtin);
292c18ec02fSPetter Reinholdtsen   if (itr == 0)
293c18ec02fSPetter Reinholdtsen     return 0;
294c18ec02fSPetter Reinholdtsen 
295c18ec02fSPetter Reinholdtsen   printf("Load SDRs from 0x%x\n", from_addr);
296c18ec02fSPetter Reinholdtsen   rc = sdrr_get_records(intf, itr, &sdrr_queue);
297c18ec02fSPetter Reinholdtsen   ipmi_sdr_end(intf, itr);
298c18ec02fSPetter Reinholdtsen   /* ... */
299c18ec02fSPetter Reinholdtsen 
300c18ec02fSPetter Reinholdtsen   /* write the SDRs to the destination SDR Repository */
301c18ec02fSPetter Reinholdtsen   intf->target_addr = to_addr;
302c18ec02fSPetter Reinholdtsen   for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) {
303c18ec02fSPetter Reinholdtsen     sdrr_next = sdrr->next;
304c18ec02fSPetter Reinholdtsen     rc = ipmi_sdr_add_record(intf, sdrr);
305c18ec02fSPetter Reinholdtsen     if(rc < 0){
306c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id);
307c18ec02fSPetter Reinholdtsen     }
308c18ec02fSPetter Reinholdtsen     free(sdrr);
309c18ec02fSPetter Reinholdtsen     sdrr = NULL;
310c18ec02fSPetter Reinholdtsen   }
311c18ec02fSPetter Reinholdtsen   return rc;
312c18ec02fSPetter Reinholdtsen }
313c18ec02fSPetter Reinholdtsen 
314c18ec02fSPetter Reinholdtsen int
ipmi_sdr_add_from_sensors(struct ipmi_intf * intf,int maxslot)315c18ec02fSPetter Reinholdtsen ipmi_sdr_add_from_sensors(struct ipmi_intf *intf, int maxslot)
316c18ec02fSPetter Reinholdtsen {
317c18ec02fSPetter Reinholdtsen   int i;
318c18ec02fSPetter Reinholdtsen   int rc = 0;
319c18ec02fSPetter Reinholdtsen   int slave_addr;
320c18ec02fSPetter Reinholdtsen   int myaddr = intf->target_addr;
321c18ec02fSPetter Reinholdtsen 
322c18ec02fSPetter Reinholdtsen   if (ipmi_sdr_repo_clear(intf)) {
323c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "Cannot erase SDRR. Give up.");
324c18ec02fSPetter Reinholdtsen     return -1;
325c18ec02fSPetter Reinholdtsen   }
326c18ec02fSPetter Reinholdtsen 
327c18ec02fSPetter Reinholdtsen   /* First fill the SDRR from local built-in sensors */
328c18ec02fSPetter Reinholdtsen   rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr);
329c18ec02fSPetter Reinholdtsen 
330c18ec02fSPetter Reinholdtsen   /* Now fill the SDRR with remote sensors */
331c18ec02fSPetter Reinholdtsen   if( maxslot != 0 ) {
332c18ec02fSPetter Reinholdtsen      for (i = 0, slave_addr = 0xB0; i < maxslot; i++, slave_addr += 2) {
333c18ec02fSPetter Reinholdtsen         /* Hole in the PICMG 2.9 mapping */
334c18ec02fSPetter Reinholdtsen         if (slave_addr == 0xC2) slave_addr += 2;
335c18ec02fSPetter Reinholdtsen         if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0)
336c18ec02fSPetter Reinholdtsen         {
337c18ec02fSPetter Reinholdtsen            rc = -1;
338c18ec02fSPetter Reinholdtsen         }
339c18ec02fSPetter Reinholdtsen      }
340c18ec02fSPetter Reinholdtsen   }
341c18ec02fSPetter Reinholdtsen   return rc;
342c18ec02fSPetter Reinholdtsen }
343c18ec02fSPetter Reinholdtsen 
ipmi_hex_to_dec(char * strchar,unsigned char * pDecValue)344c18ec02fSPetter Reinholdtsen int ipmi_hex_to_dec( char * strchar, unsigned char * pDecValue)
345c18ec02fSPetter Reinholdtsen {
346c18ec02fSPetter Reinholdtsen   int rc = -1;
347c18ec02fSPetter Reinholdtsen   unsigned char retValue = 0;
348c18ec02fSPetter Reinholdtsen 
349c18ec02fSPetter Reinholdtsen   if(
350c18ec02fSPetter Reinholdtsen      (strlen(strchar) == 4)
351c18ec02fSPetter Reinholdtsen      &&
352c18ec02fSPetter Reinholdtsen      (strchar[0] == '0')
353c18ec02fSPetter Reinholdtsen      &&
354c18ec02fSPetter Reinholdtsen      (strchar[1] == 'x')
355c18ec02fSPetter Reinholdtsen     )
356c18ec02fSPetter Reinholdtsen   {
357c18ec02fSPetter Reinholdtsen       rc = 0;
358c18ec02fSPetter Reinholdtsen 
359c18ec02fSPetter Reinholdtsen       if((strchar[2] >= '0') && (strchar[2] <= '9'))
360c18ec02fSPetter Reinholdtsen       {
361c18ec02fSPetter Reinholdtsen         retValue += ((strchar[2]-'0') * 16);
362c18ec02fSPetter Reinholdtsen       }
363c18ec02fSPetter Reinholdtsen       else if((strchar[2] >= 'a') && (strchar[2] <= 'f'))
364c18ec02fSPetter Reinholdtsen       {
365c18ec02fSPetter Reinholdtsen         retValue += (((strchar[2]-'a') + 10) * 16);
366c18ec02fSPetter Reinholdtsen       }
367c18ec02fSPetter Reinholdtsen       else if((strchar[2] >= 'A') && (strchar[2] <= 'F'))
368c18ec02fSPetter Reinholdtsen       {
369c18ec02fSPetter Reinholdtsen         retValue += (((strchar[2]-'A') + 10) * 16);
370c18ec02fSPetter Reinholdtsen       }
371c18ec02fSPetter Reinholdtsen       else
372c18ec02fSPetter Reinholdtsen       {
373c18ec02fSPetter Reinholdtsen         rc = -1;
374c18ec02fSPetter Reinholdtsen       }
375c18ec02fSPetter Reinholdtsen 
376c18ec02fSPetter Reinholdtsen       if((strchar[3] >= '0') && (strchar[3] <= '9'))
377c18ec02fSPetter Reinholdtsen       {
378c18ec02fSPetter Reinholdtsen         retValue += ((strchar[3]-'0'));
379c18ec02fSPetter Reinholdtsen       }
380c18ec02fSPetter Reinholdtsen       else if((strchar[3] >= 'a') && (strchar[3] <= 'f'))
381c18ec02fSPetter Reinholdtsen       {
382c18ec02fSPetter Reinholdtsen         retValue += (((strchar[3]-'a') + 10));
383c18ec02fSPetter Reinholdtsen       }
384c18ec02fSPetter Reinholdtsen       else if((strchar[3] >= 'A') && (strchar[3] <= 'F'))
385c18ec02fSPetter Reinholdtsen       {
386c18ec02fSPetter Reinholdtsen         retValue += (((strchar[3]-'A') + 10));
387c18ec02fSPetter Reinholdtsen       }
388c18ec02fSPetter Reinholdtsen       else
389c18ec02fSPetter Reinholdtsen       {
390c18ec02fSPetter Reinholdtsen         rc = -1;
391c18ec02fSPetter Reinholdtsen       }
392c18ec02fSPetter Reinholdtsen   }
393c18ec02fSPetter Reinholdtsen 
394c18ec02fSPetter Reinholdtsen   if(rc == 0)
395c18ec02fSPetter Reinholdtsen   {
396c18ec02fSPetter Reinholdtsen     * pDecValue = retValue;
397c18ec02fSPetter Reinholdtsen   }
398c18ec02fSPetter Reinholdtsen   else
399c18ec02fSPetter Reinholdtsen   {
400c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "Must be Hex value of 4 characters (Ex.: 0x24)");
401c18ec02fSPetter Reinholdtsen   }
402c18ec02fSPetter Reinholdtsen 
403c18ec02fSPetter Reinholdtsen   return rc;
404c18ec02fSPetter Reinholdtsen }
405c18ec02fSPetter Reinholdtsen 
406c18ec02fSPetter Reinholdtsen 
407c18ec02fSPetter Reinholdtsen 
408c18ec02fSPetter Reinholdtsen #define MAX_NUM_SLOT  128
ipmi_parse_range_list(const char * rangeList,unsigned char * pHexList)409c18ec02fSPetter Reinholdtsen int ipmi_parse_range_list(const char *rangeList, unsigned char * pHexList)
410c18ec02fSPetter Reinholdtsen {
411c18ec02fSPetter Reinholdtsen   int rc = -1;
412c18ec02fSPetter Reinholdtsen 
413c18ec02fSPetter Reinholdtsen   unsigned char listOffset = 0;
414c18ec02fSPetter Reinholdtsen   char * nextString;
415c18ec02fSPetter Reinholdtsen   char * rangeString;
416c18ec02fSPetter Reinholdtsen   char * inProcessString = (char *) rangeList;
417c18ec02fSPetter Reinholdtsen 
418c18ec02fSPetter Reinholdtsen   /* Discard empty string */
419c18ec02fSPetter Reinholdtsen   if(strlen(rangeList) == 0)
420c18ec02fSPetter Reinholdtsen   {
421c18ec02fSPetter Reinholdtsen     return rc;
422c18ec02fSPetter Reinholdtsen   }
423c18ec02fSPetter Reinholdtsen 
424c18ec02fSPetter Reinholdtsen   /* First, cut to comma separated string */
425c18ec02fSPetter Reinholdtsen   nextString = strstr( rangeList, "," );
426c18ec02fSPetter Reinholdtsen 
427c18ec02fSPetter Reinholdtsen   if(nextString != rangeList)
428c18ec02fSPetter Reinholdtsen   {
429c18ec02fSPetter Reinholdtsen     unsigned char isLast;
430c18ec02fSPetter Reinholdtsen     /* We get a valid string so far */
431c18ec02fSPetter Reinholdtsen     rc = 0;
432c18ec02fSPetter Reinholdtsen 
433c18ec02fSPetter Reinholdtsen     do
434c18ec02fSPetter Reinholdtsen     {
435c18ec02fSPetter Reinholdtsen       if(nextString != NULL)
436c18ec02fSPetter Reinholdtsen       {
437c18ec02fSPetter Reinholdtsen         (*nextString)= 0;
438c18ec02fSPetter Reinholdtsen         nextString   ++;
439c18ec02fSPetter Reinholdtsen         isLast = 0;
440c18ec02fSPetter Reinholdtsen       }
441c18ec02fSPetter Reinholdtsen       else
442c18ec02fSPetter Reinholdtsen       {
443c18ec02fSPetter Reinholdtsen         isLast = 1;
444c18ec02fSPetter Reinholdtsen       }
445c18ec02fSPetter Reinholdtsen 
446c18ec02fSPetter Reinholdtsen       /* At this point, it is a single entry or a range */
447c18ec02fSPetter Reinholdtsen       rangeString = strstr( inProcessString, "-" );
448c18ec02fSPetter Reinholdtsen       if(rangeString == NULL)
449c18ec02fSPetter Reinholdtsen       {
450c18ec02fSPetter Reinholdtsen         unsigned char decValue = 0;
451c18ec02fSPetter Reinholdtsen 
452c18ec02fSPetter Reinholdtsen         /* Single entry */
453c18ec02fSPetter Reinholdtsen         rc = ipmi_hex_to_dec( inProcessString, &decValue);
454c18ec02fSPetter Reinholdtsen 
455c18ec02fSPetter Reinholdtsen         if(rc == 0)
456c18ec02fSPetter Reinholdtsen         {
457c18ec02fSPetter Reinholdtsen           if((decValue % 2) == 0)
458c18ec02fSPetter Reinholdtsen           {
459c18ec02fSPetter Reinholdtsen             pHexList[listOffset++] = decValue;
460c18ec02fSPetter Reinholdtsen           }
461c18ec02fSPetter Reinholdtsen           else
462c18ec02fSPetter Reinholdtsen           {
463c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "I2C address provided value must be even.");
464c18ec02fSPetter Reinholdtsen           }
465c18ec02fSPetter Reinholdtsen         }
466c18ec02fSPetter Reinholdtsen       }
467c18ec02fSPetter Reinholdtsen       else
468c18ec02fSPetter Reinholdtsen       {
469c18ec02fSPetter Reinholdtsen         unsigned char startValue = 0;
470c18ec02fSPetter Reinholdtsen         unsigned char endValue = 0;
471c18ec02fSPetter Reinholdtsen 
472c18ec02fSPetter Reinholdtsen 
473c18ec02fSPetter Reinholdtsen         (*rangeString)= 0; /* Cut string*/
474c18ec02fSPetter Reinholdtsen         rangeString ++;
475c18ec02fSPetter Reinholdtsen 
476c18ec02fSPetter Reinholdtsen         /* Range */
477c18ec02fSPetter Reinholdtsen         rc = ipmi_hex_to_dec( inProcessString, &startValue);
478c18ec02fSPetter Reinholdtsen         if(rc == 0)
479c18ec02fSPetter Reinholdtsen           rc = ipmi_hex_to_dec( rangeString, &endValue);
480c18ec02fSPetter Reinholdtsen 
481c18ec02fSPetter Reinholdtsen         if(rc == 0)
482c18ec02fSPetter Reinholdtsen         {
483c18ec02fSPetter Reinholdtsen           if(((startValue % 2) == 0) && ((endValue % 2) == 0))
484c18ec02fSPetter Reinholdtsen           {
485c18ec02fSPetter Reinholdtsen             do
486c18ec02fSPetter Reinholdtsen             {
487c18ec02fSPetter Reinholdtsen               pHexList[listOffset++] = startValue;
488c18ec02fSPetter Reinholdtsen               startValue += 2;
489c18ec02fSPetter Reinholdtsen             }
490c18ec02fSPetter Reinholdtsen             while(startValue != endValue);
491c18ec02fSPetter Reinholdtsen             pHexList[listOffset++] = endValue;
492c18ec02fSPetter Reinholdtsen           }
493c18ec02fSPetter Reinholdtsen           else
494c18ec02fSPetter Reinholdtsen           {
495c18ec02fSPetter Reinholdtsen             lprintf(LOG_ERR, "I2C address provided value must be even.");
496c18ec02fSPetter Reinholdtsen           }
497c18ec02fSPetter Reinholdtsen         }
498c18ec02fSPetter Reinholdtsen       }
499c18ec02fSPetter Reinholdtsen 
500c18ec02fSPetter Reinholdtsen       if(isLast == 0)
501c18ec02fSPetter Reinholdtsen       {
502c18ec02fSPetter Reinholdtsen         /* Setup for next string */
503c18ec02fSPetter Reinholdtsen         inProcessString = nextString;
504c18ec02fSPetter Reinholdtsen         nextString = strstr( rangeList, "," );
505c18ec02fSPetter Reinholdtsen       }
506c18ec02fSPetter Reinholdtsen     }while ((isLast == 0) && (rc == 0));
507c18ec02fSPetter Reinholdtsen   }
508c18ec02fSPetter Reinholdtsen 
509c18ec02fSPetter Reinholdtsen   return rc;
510c18ec02fSPetter Reinholdtsen }
511c18ec02fSPetter Reinholdtsen 
512c18ec02fSPetter Reinholdtsen int
ipmi_sdr_add_from_list(struct ipmi_intf * intf,const char * rangeList)513c18ec02fSPetter Reinholdtsen ipmi_sdr_add_from_list(struct ipmi_intf *intf, const char *rangeList)
514c18ec02fSPetter Reinholdtsen {
515c18ec02fSPetter Reinholdtsen   int rc = 0;
516c18ec02fSPetter Reinholdtsen   int slave_addr;
517c18ec02fSPetter Reinholdtsen   int myaddr = intf->target_addr;
518c18ec02fSPetter Reinholdtsen   unsigned char listValue[MAX_NUM_SLOT];
519c18ec02fSPetter Reinholdtsen 
520c18ec02fSPetter Reinholdtsen   memset( listValue, 0, MAX_NUM_SLOT );
521c18ec02fSPetter Reinholdtsen 
522c18ec02fSPetter Reinholdtsen   /* Build list from string */
523c18ec02fSPetter Reinholdtsen   if(ipmi_parse_range_list(rangeList, listValue) != 0)
524c18ec02fSPetter Reinholdtsen   {
525c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "Range - List invalid, cannot be parsed.");
526c18ec02fSPetter Reinholdtsen     return -1;
527c18ec02fSPetter Reinholdtsen   }
528c18ec02fSPetter Reinholdtsen 
529c18ec02fSPetter Reinholdtsen   {
530c18ec02fSPetter Reinholdtsen     unsigned char counter = 0;
531c18ec02fSPetter Reinholdtsen     printf("List to scan: (Built-in) ");
532c18ec02fSPetter Reinholdtsen     while(listValue[counter] != 0)
533c18ec02fSPetter Reinholdtsen     {
534c18ec02fSPetter Reinholdtsen       printf("%02x ", listValue[counter]);
535c18ec02fSPetter Reinholdtsen       counter++;
536c18ec02fSPetter Reinholdtsen     }
537c18ec02fSPetter Reinholdtsen     printf("\n");
538c18ec02fSPetter Reinholdtsen   }
539c18ec02fSPetter Reinholdtsen 
540c18ec02fSPetter Reinholdtsen   printf("Clearing SDR Repository\n");
541c18ec02fSPetter Reinholdtsen   if (ipmi_sdr_repo_clear(intf)) {
542c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "Cannot erase SDRR. Give up.");
543c18ec02fSPetter Reinholdtsen     return -1;
544c18ec02fSPetter Reinholdtsen   }
545c18ec02fSPetter Reinholdtsen 
546c18ec02fSPetter Reinholdtsen   /* First fill the SDRR from local built-in sensors */
547c18ec02fSPetter Reinholdtsen   printf("Sanning built-in sensors..\n");
548c18ec02fSPetter Reinholdtsen   rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr);
549c18ec02fSPetter Reinholdtsen 
550c18ec02fSPetter Reinholdtsen   /* Now fill the SDRR with provided sensors list */
551c18ec02fSPetter Reinholdtsen   {
552c18ec02fSPetter Reinholdtsen     unsigned char counter = 0;
553c18ec02fSPetter Reinholdtsen     while((rc == 0) && (listValue[counter] != 0))
554c18ec02fSPetter Reinholdtsen     {
555c18ec02fSPetter Reinholdtsen       slave_addr = listValue[counter];
556c18ec02fSPetter Reinholdtsen       printf("Scanning %02Xh..\n", slave_addr);
557c18ec02fSPetter Reinholdtsen       if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0)
558c18ec02fSPetter Reinholdtsen       {
559c18ec02fSPetter Reinholdtsen          rc = -1;
560c18ec02fSPetter Reinholdtsen       }
561c18ec02fSPetter Reinholdtsen       counter++;
562c18ec02fSPetter Reinholdtsen     }
563c18ec02fSPetter Reinholdtsen   }
564c18ec02fSPetter Reinholdtsen 
565c18ec02fSPetter Reinholdtsen   return rc;
566c18ec02fSPetter Reinholdtsen }
567c18ec02fSPetter Reinholdtsen 
568c18ec02fSPetter Reinholdtsen 
569c18ec02fSPetter Reinholdtsen /*
570c18ec02fSPetter Reinholdtsen  * Fill the SDR repository from records stored in a binary file
571c18ec02fSPetter Reinholdtsen  *
572c18ec02fSPetter Reinholdtsen  */
573c18ec02fSPetter Reinholdtsen 
574c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_read_records(const char * filename,struct sdrr_queue * queue)575c18ec02fSPetter Reinholdtsen ipmi_sdr_read_records(const char *filename, struct sdrr_queue *queue)
576c18ec02fSPetter Reinholdtsen {
577c18ec02fSPetter Reinholdtsen   int rc = 0;
578c18ec02fSPetter Reinholdtsen   int fd;
579c18ec02fSPetter Reinholdtsen   uint8_t binHdr[5];
580c18ec02fSPetter Reinholdtsen 
581c18ec02fSPetter Reinholdtsen   queue->head = NULL;
582c18ec02fSPetter Reinholdtsen   queue->tail = NULL;
583c18ec02fSPetter Reinholdtsen 
584c18ec02fSPetter Reinholdtsen   if ((fd = open(filename, O_RDONLY)) < 0) {
585c18ec02fSPetter Reinholdtsen     return -1;
586c18ec02fSPetter Reinholdtsen   }
587c18ec02fSPetter Reinholdtsen 
588c18ec02fSPetter Reinholdtsen   while (read(fd, binHdr, 5) == 5) {
589c18ec02fSPetter Reinholdtsen 
590c18ec02fSPetter Reinholdtsen     struct sdr_record_list *sdrr;
591c18ec02fSPetter Reinholdtsen 
592c18ec02fSPetter Reinholdtsen     lprintf(LOG_DEBUG, "binHdr[0] (id[MSB]) = 0x%02x", binHdr[0]);
593c18ec02fSPetter Reinholdtsen     lprintf(LOG_DEBUG, "binHdr[1] (id[LSB]) = 0x%02x", binHdr[1]);
594c18ec02fSPetter Reinholdtsen     lprintf(LOG_DEBUG, "binHdr[2] (version) = 0x%02x", binHdr[2]);
595c18ec02fSPetter Reinholdtsen     lprintf(LOG_DEBUG, "binHdr[3] (type) = 0x%02x", binHdr[3]);
596c18ec02fSPetter Reinholdtsen     lprintf(LOG_DEBUG, "binHdr[4] (length) = 0x%02x", binHdr[4]);
597c18ec02fSPetter Reinholdtsen 
598c18ec02fSPetter Reinholdtsen     sdrr = malloc(sizeof(*sdrr));
599c18ec02fSPetter Reinholdtsen     if (sdrr == NULL) {
600c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "ipmitool: malloc failure");
601c18ec02fSPetter Reinholdtsen       rc = -1;
602c18ec02fSPetter Reinholdtsen       break;
603c18ec02fSPetter Reinholdtsen     }
604c18ec02fSPetter Reinholdtsen     sdrr->id = (binHdr[1] << 8) | binHdr[0];  // LS Byte first
605c18ec02fSPetter Reinholdtsen     sdrr->version = binHdr[2];
606c18ec02fSPetter Reinholdtsen     sdrr->type = binHdr[3];
607c18ec02fSPetter Reinholdtsen     sdrr->length = binHdr[4];
608c18ec02fSPetter Reinholdtsen 
609c18ec02fSPetter Reinholdtsen     if ((sdrr->raw = malloc(sdrr->length)) == NULL) {
610c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "ipmitool: malloc failure");
611c18ec02fSPetter Reinholdtsen       free(sdrr);
612c18ec02fSPetter Reinholdtsen       sdrr = NULL;
613c18ec02fSPetter Reinholdtsen       rc = -1;
614c18ec02fSPetter Reinholdtsen       break;
615c18ec02fSPetter Reinholdtsen     }
616c18ec02fSPetter Reinholdtsen 
617c18ec02fSPetter Reinholdtsen     if (read(fd, sdrr->raw, sdrr->length) != sdrr->length) {
618c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "SDR from '%s' truncated", filename);
619c18ec02fSPetter Reinholdtsen       free(sdrr->raw);
620c18ec02fSPetter Reinholdtsen       sdrr->raw = NULL;
621c18ec02fSPetter Reinholdtsen       free(sdrr);
622c18ec02fSPetter Reinholdtsen       sdrr = NULL;
623c18ec02fSPetter Reinholdtsen       rc = -1;
624c18ec02fSPetter Reinholdtsen       break;
625c18ec02fSPetter Reinholdtsen     }
626c18ec02fSPetter Reinholdtsen 
627c18ec02fSPetter Reinholdtsen     /* put in the record queue */
628c18ec02fSPetter Reinholdtsen     if (queue->head == NULL)
629c18ec02fSPetter Reinholdtsen       queue->head = sdrr;
630c18ec02fSPetter Reinholdtsen     else
631c18ec02fSPetter Reinholdtsen       queue->tail->next = sdrr;
632c18ec02fSPetter Reinholdtsen     queue->tail = sdrr;
633c18ec02fSPetter Reinholdtsen   }
634*e9c3de03SZdenek Styblik   close(fd);
635c18ec02fSPetter Reinholdtsen   return rc;
636c18ec02fSPetter Reinholdtsen }
637c18ec02fSPetter Reinholdtsen 
638c18ec02fSPetter Reinholdtsen int
ipmi_sdr_add_from_file(struct ipmi_intf * intf,const char * ifile)639c18ec02fSPetter Reinholdtsen ipmi_sdr_add_from_file(struct ipmi_intf *intf, const char *ifile)
640c18ec02fSPetter Reinholdtsen {
641c18ec02fSPetter Reinholdtsen   int rc;
642c18ec02fSPetter Reinholdtsen   struct sdrr_queue sdrr_queue;
643c18ec02fSPetter Reinholdtsen   struct sdr_record_list *sdrr;
644c18ec02fSPetter Reinholdtsen   struct sdr_record_list *sdrr_next;
645c18ec02fSPetter Reinholdtsen 
646c18ec02fSPetter Reinholdtsen   /* read the SDR records from file */
647c18ec02fSPetter Reinholdtsen   rc = ipmi_sdr_read_records(ifile, &sdrr_queue);
648c18ec02fSPetter Reinholdtsen 
649c18ec02fSPetter Reinholdtsen   if (ipmi_sdr_repo_clear(intf)) {
650c18ec02fSPetter Reinholdtsen     lprintf(LOG_ERR, "Cannot erase SDRR. Giving up.");
651c18ec02fSPetter Reinholdtsen     /* FIXME: free sdr list */
652c18ec02fSPetter Reinholdtsen     return -1;
653c18ec02fSPetter Reinholdtsen   }
654c18ec02fSPetter Reinholdtsen 
655c18ec02fSPetter Reinholdtsen   /* write the SDRs to the SDR Repository */
656c18ec02fSPetter Reinholdtsen   for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) {
657c18ec02fSPetter Reinholdtsen     sdrr_next = sdrr->next;
658c18ec02fSPetter Reinholdtsen     rc = ipmi_sdr_add_record(intf, sdrr);
659c18ec02fSPetter Reinholdtsen     if(rc < 0){
660c18ec02fSPetter Reinholdtsen       lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id);
661c18ec02fSPetter Reinholdtsen     }
662c18ec02fSPetter Reinholdtsen     free(sdrr);
663c18ec02fSPetter Reinholdtsen     sdrr = NULL;
664c18ec02fSPetter Reinholdtsen   }
665c18ec02fSPetter Reinholdtsen   return rc;
666c18ec02fSPetter Reinholdtsen }
667c18ec02fSPetter Reinholdtsen 
668