Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / char / ipmi / ipmi_smic_sm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * ipmi_smic_sm.c
4  *
5  * The state-machine driver for an IPMI SMIC driver
6  *
7  * It started as a copy of Corey Minyard's driver for the KSC interface
8  * and the kernel patch "mmcdev-patch-245" by HP
9  *
10  * modified by: Hannes Schulz <schulz@schwaar.com>
11  *              ipmi@schwaar.com
12  *
13  *
14  * Corey Minyard's driver for the KSC interface has the following
15  * copyright notice:
16  *   Copyright 2002 MontaVista Software Inc.
17  *
18  * the kernel patch "mmcdev-patch-245" by HP has the following
19  * copyright notice:
20  * (c) Copyright 2001 Grant Grundler (c) Copyright
21  * 2001 Hewlett-Packard Company
22  */
23
24 #include <linux/kernel.h> /* For printk. */
25 #include <linux/string.h>
26 #include <linux/module.h>
27 #include <linux/moduleparam.h>
28 #include <linux/ipmi_msgdefs.h>         /* for completion codes */
29 #include "ipmi_si_sm.h"
30
31 /* smic_debug is a bit-field
32  *      SMIC_DEBUG_ENABLE -     turned on for now
33  *      SMIC_DEBUG_MSG -        commands and their responses
34  *      SMIC_DEBUG_STATES -     state machine
35 */
36 #define SMIC_DEBUG_STATES       4
37 #define SMIC_DEBUG_MSG          2
38 #define SMIC_DEBUG_ENABLE       1
39
40 static int smic_debug = 1;
41 module_param(smic_debug, int, 0644);
42 MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
43
44 enum smic_states {
45         SMIC_IDLE,
46         SMIC_START_OP,
47         SMIC_OP_OK,
48         SMIC_WRITE_START,
49         SMIC_WRITE_NEXT,
50         SMIC_WRITE_END,
51         SMIC_WRITE2READ,
52         SMIC_READ_START,
53         SMIC_READ_NEXT,
54         SMIC_READ_END,
55         SMIC_HOSED
56 };
57
58 #define MAX_SMIC_READ_SIZE 80
59 #define MAX_SMIC_WRITE_SIZE 80
60 #define SMIC_MAX_ERROR_RETRIES 3
61
62 /* Timeouts in microseconds. */
63 #define SMIC_RETRY_TIMEOUT (2*USEC_PER_SEC)
64
65 /* SMIC Flags Register Bits */
66 #define SMIC_RX_DATA_READY      0x80
67 #define SMIC_TX_DATA_READY      0x40
68
69 /*
70  * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
71  * a few systems, and then only by Systems Management
72  * Interrupts, not by the OS.  Always ignore these bits.
73  *
74  */
75 #define SMIC_SMI                0x10
76 #define SMIC_EVM_DATA_AVAIL     0x08
77 #define SMIC_SMS_DATA_AVAIL     0x04
78 #define SMIC_FLAG_BSY           0x01
79
80 /* SMIC Error Codes */
81 #define EC_NO_ERROR             0x00
82 #define EC_ABORTED              0x01
83 #define EC_ILLEGAL_CONTROL      0x02
84 #define EC_NO_RESPONSE          0x03
85 #define EC_ILLEGAL_COMMAND      0x04
86 #define EC_BUFFER_FULL          0x05
87
88 struct si_sm_data {
89         enum smic_states state;
90         struct si_sm_io *io;
91         unsigned char    write_data[MAX_SMIC_WRITE_SIZE];
92         int              write_pos;
93         int              write_count;
94         int              orig_write_count;
95         unsigned char    read_data[MAX_SMIC_READ_SIZE];
96         int              read_pos;
97         int              truncated;
98         unsigned int     error_retries;
99         long             smic_timeout;
100 };
101
102 static unsigned int init_smic_data(struct si_sm_data *smic,
103                                    struct si_sm_io *io)
104 {
105         smic->state = SMIC_IDLE;
106         smic->io = io;
107         smic->write_pos = 0;
108         smic->write_count = 0;
109         smic->orig_write_count = 0;
110         smic->read_pos = 0;
111         smic->error_retries = 0;
112         smic->truncated = 0;
113         smic->smic_timeout = SMIC_RETRY_TIMEOUT;
114
115         /* We use 3 bytes of I/O. */
116         return 3;
117 }
118
119 static int start_smic_transaction(struct si_sm_data *smic,
120                                   unsigned char *data, unsigned int size)
121 {
122         unsigned int i;
123
124         if (size < 2)
125                 return IPMI_REQ_LEN_INVALID_ERR;
126         if (size > MAX_SMIC_WRITE_SIZE)
127                 return IPMI_REQ_LEN_EXCEEDED_ERR;
128
129         if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED))
130                 return IPMI_NOT_IN_MY_STATE_ERR;
131
132         if (smic_debug & SMIC_DEBUG_MSG) {
133                 printk(KERN_DEBUG "start_smic_transaction -");
134                 for (i = 0; i < size; i++)
135                         pr_cont(" %02x", data[i]);
136                 pr_cont("\n");
137         }
138         smic->error_retries = 0;
139         memcpy(smic->write_data, data, size);
140         smic->write_count = size;
141         smic->orig_write_count = size;
142         smic->write_pos = 0;
143         smic->read_pos = 0;
144         smic->state = SMIC_START_OP;
145         smic->smic_timeout = SMIC_RETRY_TIMEOUT;
146         return 0;
147 }
148
149 static int smic_get_result(struct si_sm_data *smic,
150                            unsigned char *data, unsigned int length)
151 {
152         int i;
153
154         if (smic_debug & SMIC_DEBUG_MSG) {
155                 printk(KERN_DEBUG "smic_get result -");
156                 for (i = 0; i < smic->read_pos; i++)
157                         pr_cont(" %02x", smic->read_data[i]);
158                 pr_cont("\n");
159         }
160         if (length < smic->read_pos) {
161                 smic->read_pos = length;
162                 smic->truncated = 1;
163         }
164         memcpy(data, smic->read_data, smic->read_pos);
165
166         if ((length >= 3) && (smic->read_pos < 3)) {
167                 data[2] = IPMI_ERR_UNSPECIFIED;
168                 smic->read_pos = 3;
169         }
170         if (smic->truncated) {
171                 data[2] = IPMI_ERR_MSG_TRUNCATED;
172                 smic->truncated = 0;
173         }
174         return smic->read_pos;
175 }
176
177 static inline unsigned char read_smic_flags(struct si_sm_data *smic)
178 {
179         return smic->io->inputb(smic->io, 2);
180 }
181
182 static inline unsigned char read_smic_status(struct si_sm_data *smic)
183 {
184         return smic->io->inputb(smic->io, 1);
185 }
186
187 static inline unsigned char read_smic_data(struct si_sm_data *smic)
188 {
189         return smic->io->inputb(smic->io, 0);
190 }
191
192 static inline void write_smic_flags(struct si_sm_data *smic,
193                                     unsigned char   flags)
194 {
195         smic->io->outputb(smic->io, 2, flags);
196 }
197
198 static inline void write_smic_control(struct si_sm_data *smic,
199                                       unsigned char   control)
200 {
201         smic->io->outputb(smic->io, 1, control);
202 }
203
204 static inline void write_si_sm_data(struct si_sm_data *smic,
205                                     unsigned char   data)
206 {
207         smic->io->outputb(smic->io, 0, data);
208 }
209
210 static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
211 {
212         (smic->error_retries)++;
213         if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
214                 if (smic_debug & SMIC_DEBUG_ENABLE)
215                         pr_warn("ipmi_smic_drv: smic hosed: %s\n", reason);
216                 smic->state = SMIC_HOSED;
217         } else {
218                 smic->write_count = smic->orig_write_count;
219                 smic->write_pos = 0;
220                 smic->read_pos = 0;
221                 smic->state = SMIC_START_OP;
222                 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
223         }
224 }
225
226 static inline void write_next_byte(struct si_sm_data *smic)
227 {
228         write_si_sm_data(smic, smic->write_data[smic->write_pos]);
229         (smic->write_pos)++;
230         (smic->write_count)--;
231 }
232
233 static inline void read_next_byte(struct si_sm_data *smic)
234 {
235         if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
236                 read_smic_data(smic);
237                 smic->truncated = 1;
238         } else {
239                 smic->read_data[smic->read_pos] = read_smic_data(smic);
240                 smic->read_pos++;
241         }
242 }
243
244 /*  SMIC Control/Status Code Components */
245 #define SMIC_GET_STATUS         0x00    /* Control form's name */
246 #define SMIC_READY              0x00    /* Status  form's name */
247 #define SMIC_WR_START           0x01    /* Unified Control/Status names... */
248 #define SMIC_WR_NEXT            0x02
249 #define SMIC_WR_END             0x03
250 #define SMIC_RD_START           0x04
251 #define SMIC_RD_NEXT            0x05
252 #define SMIC_RD_END             0x06
253 #define SMIC_CODE_MASK          0x0f
254
255 #define SMIC_CONTROL            0x00
256 #define SMIC_STATUS             0x80
257 #define SMIC_CS_MASK            0x80
258
259 #define SMIC_SMS                0x40
260 #define SMIC_SMM                0x60
261 #define SMIC_STREAM_MASK        0x60
262
263 /*  SMIC Control Codes */
264 #define SMIC_CC_SMS_GET_STATUS  (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
265 #define SMIC_CC_SMS_WR_START    (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
266 #define SMIC_CC_SMS_WR_NEXT     (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
267 #define SMIC_CC_SMS_WR_END      (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
268 #define SMIC_CC_SMS_RD_START    (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
269 #define SMIC_CC_SMS_RD_NEXT     (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
270 #define SMIC_CC_SMS_RD_END      (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
271
272 #define SMIC_CC_SMM_GET_STATUS  (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
273 #define SMIC_CC_SMM_WR_START    (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
274 #define SMIC_CC_SMM_WR_NEXT     (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
275 #define SMIC_CC_SMM_WR_END      (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
276 #define SMIC_CC_SMM_RD_START    (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
277 #define SMIC_CC_SMM_RD_NEXT     (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
278 #define SMIC_CC_SMM_RD_END      (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
279
280 /*  SMIC Status Codes */
281 #define SMIC_SC_SMS_READY       (SMIC_STATUS|SMIC_SMS|SMIC_READY)
282 #define SMIC_SC_SMS_WR_START    (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
283 #define SMIC_SC_SMS_WR_NEXT     (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
284 #define SMIC_SC_SMS_WR_END      (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
285 #define SMIC_SC_SMS_RD_START    (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
286 #define SMIC_SC_SMS_RD_NEXT     (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
287 #define SMIC_SC_SMS_RD_END      (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
288
289 #define SMIC_SC_SMM_READY       (SMIC_STATUS|SMIC_SMM|SMIC_READY)
290 #define SMIC_SC_SMM_WR_START    (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
291 #define SMIC_SC_SMM_WR_NEXT     (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
292 #define SMIC_SC_SMM_WR_END      (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
293 #define SMIC_SC_SMM_RD_START    (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
294 #define SMIC_SC_SMM_RD_NEXT     (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
295 #define SMIC_SC_SMM_RD_END      (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
296
297 /* these are the control/status codes we actually use
298         SMIC_CC_SMS_GET_STATUS  0x40
299         SMIC_CC_SMS_WR_START    0x41
300         SMIC_CC_SMS_WR_NEXT     0x42
301         SMIC_CC_SMS_WR_END      0x43
302         SMIC_CC_SMS_RD_START    0x44
303         SMIC_CC_SMS_RD_NEXT     0x45
304         SMIC_CC_SMS_RD_END      0x46
305
306         SMIC_SC_SMS_READY       0xC0
307         SMIC_SC_SMS_WR_START    0xC1
308         SMIC_SC_SMS_WR_NEXT     0xC2
309         SMIC_SC_SMS_WR_END      0xC3
310         SMIC_SC_SMS_RD_START    0xC4
311         SMIC_SC_SMS_RD_NEXT     0xC5
312         SMIC_SC_SMS_RD_END      0xC6
313 */
314
315 static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
316 {
317         unsigned char status;
318         unsigned char flags;
319         unsigned char data;
320
321         if (smic->state == SMIC_HOSED) {
322                 init_smic_data(smic, smic->io);
323                 return SI_SM_HOSED;
324         }
325         if (smic->state != SMIC_IDLE) {
326                 if (smic_debug & SMIC_DEBUG_STATES)
327                         printk(KERN_DEBUG
328                                "smic_event - smic->smic_timeout = %ld, time = %ld\n",
329                                smic->smic_timeout, time);
330                 /*
331                  * FIXME: smic_event is sometimes called with time >
332                  * SMIC_RETRY_TIMEOUT
333                  */
334                 if (time < SMIC_RETRY_TIMEOUT) {
335                         smic->smic_timeout -= time;
336                         if (smic->smic_timeout < 0) {
337                                 start_error_recovery(smic, "smic timed out.");
338                                 return SI_SM_CALL_WITH_DELAY;
339                         }
340                 }
341         }
342         flags = read_smic_flags(smic);
343         if (flags & SMIC_FLAG_BSY)
344                 return SI_SM_CALL_WITH_DELAY;
345
346         status = read_smic_status(smic);
347         if (smic_debug & SMIC_DEBUG_STATES)
348                 printk(KERN_DEBUG "smic_event - state = %d, flags = 0x%02x, status = 0x%02x\n",
349                        smic->state, flags, status);
350
351         switch (smic->state) {
352         case SMIC_IDLE:
353                 /* in IDLE we check for available messages */
354                 if (flags & SMIC_SMS_DATA_AVAIL)
355                         return SI_SM_ATTN;
356                 return SI_SM_IDLE;
357
358         case SMIC_START_OP:
359                 /* sanity check whether smic is really idle */
360                 write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
361                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
362                 smic->state = SMIC_OP_OK;
363                 break;
364
365         case SMIC_OP_OK:
366                 if (status != SMIC_SC_SMS_READY) {
367                         /* this should not happen */
368                         start_error_recovery(smic,
369                                              "state = SMIC_OP_OK,"
370                                              " status != SMIC_SC_SMS_READY");
371                         return SI_SM_CALL_WITH_DELAY;
372                 }
373                 /* OK so far; smic is idle let us start ... */
374                 write_smic_control(smic, SMIC_CC_SMS_WR_START);
375                 write_next_byte(smic);
376                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
377                 smic->state = SMIC_WRITE_START;
378                 break;
379
380         case SMIC_WRITE_START:
381                 if (status != SMIC_SC_SMS_WR_START) {
382                         start_error_recovery(smic,
383                                              "state = SMIC_WRITE_START, "
384                                              "status != SMIC_SC_SMS_WR_START");
385                         return SI_SM_CALL_WITH_DELAY;
386                 }
387                 /*
388                  * we must not issue WR_(NEXT|END) unless
389                  * TX_DATA_READY is set
390                  * */
391                 if (flags & SMIC_TX_DATA_READY) {
392                         if (smic->write_count == 1) {
393                                 /* last byte */
394                                 write_smic_control(smic, SMIC_CC_SMS_WR_END);
395                                 smic->state = SMIC_WRITE_END;
396                         } else {
397                                 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
398                                 smic->state = SMIC_WRITE_NEXT;
399                         }
400                         write_next_byte(smic);
401                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
402                 } else
403                         return SI_SM_CALL_WITH_DELAY;
404                 break;
405
406         case SMIC_WRITE_NEXT:
407                 if (status != SMIC_SC_SMS_WR_NEXT) {
408                         start_error_recovery(smic,
409                                              "state = SMIC_WRITE_NEXT, "
410                                              "status != SMIC_SC_SMS_WR_NEXT");
411                         return SI_SM_CALL_WITH_DELAY;
412                 }
413                 /* this is the same code as in SMIC_WRITE_START */
414                 if (flags & SMIC_TX_DATA_READY) {
415                         if (smic->write_count == 1) {
416                                 write_smic_control(smic, SMIC_CC_SMS_WR_END);
417                                 smic->state = SMIC_WRITE_END;
418                         } else {
419                                 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
420                                 smic->state = SMIC_WRITE_NEXT;
421                         }
422                         write_next_byte(smic);
423                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
424                 } else
425                         return SI_SM_CALL_WITH_DELAY;
426                 break;
427
428         case SMIC_WRITE_END:
429                 if (status != SMIC_SC_SMS_WR_END) {
430                         start_error_recovery(smic,
431                                              "state = SMIC_WRITE_END, "
432                                              "status != SMIC_SC_SMS_WR_END");
433                         return SI_SM_CALL_WITH_DELAY;
434                 }
435                 /* data register holds an error code */
436                 data = read_smic_data(smic);
437                 if (data != 0) {
438                         if (smic_debug & SMIC_DEBUG_ENABLE)
439                                 printk(KERN_DEBUG "SMIC_WRITE_END: data = %02x\n",
440                                        data);
441                         start_error_recovery(smic,
442                                              "state = SMIC_WRITE_END, "
443                                              "data != SUCCESS");
444                         return SI_SM_CALL_WITH_DELAY;
445                 } else
446                         smic->state = SMIC_WRITE2READ;
447                 break;
448
449         case SMIC_WRITE2READ:
450                 /*
451                  * we must wait for RX_DATA_READY to be set before we
452                  * can continue
453                  */
454                 if (flags & SMIC_RX_DATA_READY) {
455                         write_smic_control(smic, SMIC_CC_SMS_RD_START);
456                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
457                         smic->state = SMIC_READ_START;
458                 } else
459                         return SI_SM_CALL_WITH_DELAY;
460                 break;
461
462         case SMIC_READ_START:
463                 if (status != SMIC_SC_SMS_RD_START) {
464                         start_error_recovery(smic,
465                                              "state = SMIC_READ_START, "
466                                              "status != SMIC_SC_SMS_RD_START");
467                         return SI_SM_CALL_WITH_DELAY;
468                 }
469                 if (flags & SMIC_RX_DATA_READY) {
470                         read_next_byte(smic);
471                         write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
472                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
473                         smic->state = SMIC_READ_NEXT;
474                 } else
475                         return SI_SM_CALL_WITH_DELAY;
476                 break;
477
478         case SMIC_READ_NEXT:
479                 switch (status) {
480                 /*
481                  * smic tells us that this is the last byte to be read
482                  * --> clean up
483                  */
484                 case SMIC_SC_SMS_RD_END:
485                         read_next_byte(smic);
486                         write_smic_control(smic, SMIC_CC_SMS_RD_END);
487                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
488                         smic->state = SMIC_READ_END;
489                         break;
490                 case SMIC_SC_SMS_RD_NEXT:
491                         if (flags & SMIC_RX_DATA_READY) {
492                                 read_next_byte(smic);
493                                 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
494                                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
495                                 smic->state = SMIC_READ_NEXT;
496                         } else
497                                 return SI_SM_CALL_WITH_DELAY;
498                         break;
499                 default:
500                         start_error_recovery(
501                                 smic,
502                                 "state = SMIC_READ_NEXT, "
503                                 "status != SMIC_SC_SMS_RD_(NEXT|END)");
504                         return SI_SM_CALL_WITH_DELAY;
505                 }
506                 break;
507
508         case SMIC_READ_END:
509                 if (status != SMIC_SC_SMS_READY) {
510                         start_error_recovery(smic,
511                                              "state = SMIC_READ_END, "
512                                              "status != SMIC_SC_SMS_READY");
513                         return SI_SM_CALL_WITH_DELAY;
514                 }
515                 data = read_smic_data(smic);
516                 /* data register holds an error code */
517                 if (data != 0) {
518                         if (smic_debug & SMIC_DEBUG_ENABLE)
519                                 printk(KERN_DEBUG "SMIC_READ_END: data = %02x\n",
520                                        data);
521                         start_error_recovery(smic,
522                                              "state = SMIC_READ_END, "
523                                              "data != SUCCESS");
524                         return SI_SM_CALL_WITH_DELAY;
525                 } else {
526                         smic->state = SMIC_IDLE;
527                         return SI_SM_TRANSACTION_COMPLETE;
528                 }
529
530         case SMIC_HOSED:
531                 init_smic_data(smic, smic->io);
532                 return SI_SM_HOSED;
533
534         default:
535                 if (smic_debug & SMIC_DEBUG_ENABLE) {
536                         printk(KERN_DEBUG "smic->state = %d\n", smic->state);
537                         start_error_recovery(smic, "state = UNKNOWN");
538                         return SI_SM_CALL_WITH_DELAY;
539                 }
540         }
541         smic->smic_timeout = SMIC_RETRY_TIMEOUT;
542         return SI_SM_CALL_WITHOUT_DELAY;
543 }
544
545 static int smic_detect(struct si_sm_data *smic)
546 {
547         /*
548          * It's impossible for the SMIC fnags register to be all 1's,
549          * (assuming a properly functioning, self-initialized BMC)
550          * but that's what you get from reading a bogus address, so we
551          * test that first.
552          */
553         if (read_smic_flags(smic) == 0xff)
554                 return 1;
555
556         return 0;
557 }
558
559 static void smic_cleanup(struct si_sm_data *kcs)
560 {
561 }
562
563 static int smic_size(void)
564 {
565         return sizeof(struct si_sm_data);
566 }
567
568 const struct si_sm_handlers smic_smi_handlers = {
569         .init_data         = init_smic_data,
570         .start_transaction = start_smic_transaction,
571         .get_result        = smic_get_result,
572         .event             = smic_event,
573         .detect            = smic_detect,
574         .cleanup           = smic_cleanup,
575         .size              = smic_size,
576 };