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