GNU Linux-libre 4.19.286-gnu1
[releases.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                         printk(" %02x", (unsigned char) data[i]);
136                 printk("\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                         printk(" %02x", smic->read_data[i]);
158                 printk("\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                         printk(KERN_WARNING
216                                "ipmi_smic_drv: smic hosed: %s\n", reason);
217                 smic->state = SMIC_HOSED;
218         } else {
219                 smic->write_count = smic->orig_write_count;
220                 smic->write_pos = 0;
221                 smic->read_pos = 0;
222                 smic->state = SMIC_START_OP;
223                 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
224         }
225 }
226
227 static inline void write_next_byte(struct si_sm_data *smic)
228 {
229         write_si_sm_data(smic, smic->write_data[smic->write_pos]);
230         (smic->write_pos)++;
231         (smic->write_count)--;
232 }
233
234 static inline void read_next_byte(struct si_sm_data *smic)
235 {
236         if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
237                 read_smic_data(smic);
238                 smic->truncated = 1;
239         } else {
240                 smic->read_data[smic->read_pos] = read_smic_data(smic);
241                 smic->read_pos++;
242         }
243 }
244
245 /*  SMIC Control/Status Code Components */
246 #define SMIC_GET_STATUS         0x00    /* Control form's name */
247 #define SMIC_READY              0x00    /* Status  form's name */
248 #define SMIC_WR_START           0x01    /* Unified Control/Status names... */
249 #define SMIC_WR_NEXT            0x02
250 #define SMIC_WR_END             0x03
251 #define SMIC_RD_START           0x04
252 #define SMIC_RD_NEXT            0x05
253 #define SMIC_RD_END             0x06
254 #define SMIC_CODE_MASK          0x0f
255
256 #define SMIC_CONTROL            0x00
257 #define SMIC_STATUS             0x80
258 #define SMIC_CS_MASK            0x80
259
260 #define SMIC_SMS                0x40
261 #define SMIC_SMM                0x60
262 #define SMIC_STREAM_MASK        0x60
263
264 /*  SMIC Control Codes */
265 #define SMIC_CC_SMS_GET_STATUS  (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
266 #define SMIC_CC_SMS_WR_START    (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
267 #define SMIC_CC_SMS_WR_NEXT     (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
268 #define SMIC_CC_SMS_WR_END      (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
269 #define SMIC_CC_SMS_RD_START    (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
270 #define SMIC_CC_SMS_RD_NEXT     (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
271 #define SMIC_CC_SMS_RD_END      (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
272
273 #define SMIC_CC_SMM_GET_STATUS  (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
274 #define SMIC_CC_SMM_WR_START    (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
275 #define SMIC_CC_SMM_WR_NEXT     (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
276 #define SMIC_CC_SMM_WR_END      (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
277 #define SMIC_CC_SMM_RD_START    (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
278 #define SMIC_CC_SMM_RD_NEXT     (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
279 #define SMIC_CC_SMM_RD_END      (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
280
281 /*  SMIC Status Codes */
282 #define SMIC_SC_SMS_READY       (SMIC_STATUS|SMIC_SMS|SMIC_READY)
283 #define SMIC_SC_SMS_WR_START    (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
284 #define SMIC_SC_SMS_WR_NEXT     (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
285 #define SMIC_SC_SMS_WR_END      (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
286 #define SMIC_SC_SMS_RD_START    (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
287 #define SMIC_SC_SMS_RD_NEXT     (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
288 #define SMIC_SC_SMS_RD_END      (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
289
290 #define SMIC_SC_SMM_READY       (SMIC_STATUS|SMIC_SMM|SMIC_READY)
291 #define SMIC_SC_SMM_WR_START    (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
292 #define SMIC_SC_SMM_WR_NEXT     (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
293 #define SMIC_SC_SMM_WR_END      (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
294 #define SMIC_SC_SMM_RD_START    (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
295 #define SMIC_SC_SMM_RD_NEXT     (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
296 #define SMIC_SC_SMM_RD_END      (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
297
298 /* these are the control/status codes we actually use
299         SMIC_CC_SMS_GET_STATUS  0x40
300         SMIC_CC_SMS_WR_START    0x41
301         SMIC_CC_SMS_WR_NEXT     0x42
302         SMIC_CC_SMS_WR_END      0x43
303         SMIC_CC_SMS_RD_START    0x44
304         SMIC_CC_SMS_RD_NEXT     0x45
305         SMIC_CC_SMS_RD_END      0x46
306
307         SMIC_SC_SMS_READY       0xC0
308         SMIC_SC_SMS_WR_START    0xC1
309         SMIC_SC_SMS_WR_NEXT     0xC2
310         SMIC_SC_SMS_WR_END      0xC3
311         SMIC_SC_SMS_RD_START    0xC4
312         SMIC_SC_SMS_RD_NEXT     0xC5
313         SMIC_SC_SMS_RD_END      0xC6
314 */
315
316 static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
317 {
318         unsigned char status;
319         unsigned char flags;
320         unsigned char data;
321
322         if (smic->state == SMIC_HOSED) {
323                 init_smic_data(smic, smic->io);
324                 return SI_SM_HOSED;
325         }
326         if (smic->state != SMIC_IDLE) {
327                 if (smic_debug & SMIC_DEBUG_STATES)
328                         printk(KERN_DEBUG
329                                "smic_event - smic->smic_timeout = %ld,"
330                                " time = %ld\n",
331                                smic->smic_timeout, time);
332                 /*
333                  * FIXME: smic_event is sometimes called with time >
334                  * SMIC_RETRY_TIMEOUT
335                  */
336                 if (time < SMIC_RETRY_TIMEOUT) {
337                         smic->smic_timeout -= time;
338                         if (smic->smic_timeout < 0) {
339                                 start_error_recovery(smic, "smic timed out.");
340                                 return SI_SM_CALL_WITH_DELAY;
341                         }
342                 }
343         }
344         flags = read_smic_flags(smic);
345         if (flags & SMIC_FLAG_BSY)
346                 return SI_SM_CALL_WITH_DELAY;
347
348         status = read_smic_status(smic);
349         if (smic_debug & SMIC_DEBUG_STATES)
350                 printk(KERN_DEBUG
351                        "smic_event - state = %d, flags = 0x%02x,"
352                        " status = 0x%02x\n",
353                        smic->state, flags, status);
354
355         switch (smic->state) {
356         case SMIC_IDLE:
357                 /* in IDLE we check for available messages */
358                 if (flags & SMIC_SMS_DATA_AVAIL)
359                         return SI_SM_ATTN;
360                 return SI_SM_IDLE;
361
362         case SMIC_START_OP:
363                 /* sanity check whether smic is really idle */
364                 write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
365                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
366                 smic->state = SMIC_OP_OK;
367                 break;
368
369         case SMIC_OP_OK:
370                 if (status != SMIC_SC_SMS_READY) {
371                         /* this should not happen */
372                         start_error_recovery(smic,
373                                              "state = SMIC_OP_OK,"
374                                              " status != SMIC_SC_SMS_READY");
375                         return SI_SM_CALL_WITH_DELAY;
376                 }
377                 /* OK so far; smic is idle let us start ... */
378                 write_smic_control(smic, SMIC_CC_SMS_WR_START);
379                 write_next_byte(smic);
380                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
381                 smic->state = SMIC_WRITE_START;
382                 break;
383
384         case SMIC_WRITE_START:
385                 if (status != SMIC_SC_SMS_WR_START) {
386                         start_error_recovery(smic,
387                                              "state = SMIC_WRITE_START, "
388                                              "status != SMIC_SC_SMS_WR_START");
389                         return SI_SM_CALL_WITH_DELAY;
390                 }
391                 /*
392                  * we must not issue WR_(NEXT|END) unless
393                  * TX_DATA_READY is set
394                  * */
395                 if (flags & SMIC_TX_DATA_READY) {
396                         if (smic->write_count == 1) {
397                                 /* last byte */
398                                 write_smic_control(smic, SMIC_CC_SMS_WR_END);
399                                 smic->state = SMIC_WRITE_END;
400                         } else {
401                                 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
402                                 smic->state = SMIC_WRITE_NEXT;
403                         }
404                         write_next_byte(smic);
405                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
406                 } else
407                         return SI_SM_CALL_WITH_DELAY;
408                 break;
409
410         case SMIC_WRITE_NEXT:
411                 if (status != SMIC_SC_SMS_WR_NEXT) {
412                         start_error_recovery(smic,
413                                              "state = SMIC_WRITE_NEXT, "
414                                              "status != SMIC_SC_SMS_WR_NEXT");
415                         return SI_SM_CALL_WITH_DELAY;
416                 }
417                 /* this is the same code as in SMIC_WRITE_START */
418                 if (flags & SMIC_TX_DATA_READY) {
419                         if (smic->write_count == 1) {
420                                 write_smic_control(smic, SMIC_CC_SMS_WR_END);
421                                 smic->state = SMIC_WRITE_END;
422                         } else {
423                                 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
424                                 smic->state = SMIC_WRITE_NEXT;
425                         }
426                         write_next_byte(smic);
427                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
428                 } else
429                         return SI_SM_CALL_WITH_DELAY;
430                 break;
431
432         case SMIC_WRITE_END:
433                 if (status != SMIC_SC_SMS_WR_END) {
434                         start_error_recovery(smic,
435                                              "state = SMIC_WRITE_END, "
436                                              "status != SMIC_SC_SMS_WR_END");
437                         return SI_SM_CALL_WITH_DELAY;
438                 }
439                 /* data register holds an error code */
440                 data = read_smic_data(smic);
441                 if (data != 0) {
442                         if (smic_debug & SMIC_DEBUG_ENABLE)
443                                 printk(KERN_DEBUG
444                                        "SMIC_WRITE_END: data = %02x\n", data);
445                         start_error_recovery(smic,
446                                              "state = SMIC_WRITE_END, "
447                                              "data != SUCCESS");
448                         return SI_SM_CALL_WITH_DELAY;
449                 } else
450                         smic->state = SMIC_WRITE2READ;
451                 break;
452
453         case SMIC_WRITE2READ:
454                 /*
455                  * we must wait for RX_DATA_READY to be set before we
456                  * can continue
457                  */
458                 if (flags & SMIC_RX_DATA_READY) {
459                         write_smic_control(smic, SMIC_CC_SMS_RD_START);
460                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
461                         smic->state = SMIC_READ_START;
462                 } else
463                         return SI_SM_CALL_WITH_DELAY;
464                 break;
465
466         case SMIC_READ_START:
467                 if (status != SMIC_SC_SMS_RD_START) {
468                         start_error_recovery(smic,
469                                              "state = SMIC_READ_START, "
470                                              "status != SMIC_SC_SMS_RD_START");
471                         return SI_SM_CALL_WITH_DELAY;
472                 }
473                 if (flags & SMIC_RX_DATA_READY) {
474                         read_next_byte(smic);
475                         write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
476                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
477                         smic->state = SMIC_READ_NEXT;
478                 } else
479                         return SI_SM_CALL_WITH_DELAY;
480                 break;
481
482         case SMIC_READ_NEXT:
483                 switch (status) {
484                 /*
485                  * smic tells us that this is the last byte to be read
486                  * --> clean up
487                  */
488                 case SMIC_SC_SMS_RD_END:
489                         read_next_byte(smic);
490                         write_smic_control(smic, SMIC_CC_SMS_RD_END);
491                         write_smic_flags(smic, flags | SMIC_FLAG_BSY);
492                         smic->state = SMIC_READ_END;
493                         break;
494                 case SMIC_SC_SMS_RD_NEXT:
495                         if (flags & SMIC_RX_DATA_READY) {
496                                 read_next_byte(smic);
497                                 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
498                                 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
499                                 smic->state = SMIC_READ_NEXT;
500                         } else
501                                 return SI_SM_CALL_WITH_DELAY;
502                         break;
503                 default:
504                         start_error_recovery(
505                                 smic,
506                                 "state = SMIC_READ_NEXT, "
507                                 "status != SMIC_SC_SMS_RD_(NEXT|END)");
508                         return SI_SM_CALL_WITH_DELAY;
509                 }
510                 break;
511
512         case SMIC_READ_END:
513                 if (status != SMIC_SC_SMS_READY) {
514                         start_error_recovery(smic,
515                                              "state = SMIC_READ_END, "
516                                              "status != SMIC_SC_SMS_READY");
517                         return SI_SM_CALL_WITH_DELAY;
518                 }
519                 data = read_smic_data(smic);
520                 /* data register holds an error code */
521                 if (data != 0) {
522                         if (smic_debug & SMIC_DEBUG_ENABLE)
523                                 printk(KERN_DEBUG
524                                        "SMIC_READ_END: data = %02x\n", data);
525                         start_error_recovery(smic,
526                                              "state = SMIC_READ_END, "
527                                              "data != SUCCESS");
528                         return SI_SM_CALL_WITH_DELAY;
529                 } else {
530                         smic->state = SMIC_IDLE;
531                         return SI_SM_TRANSACTION_COMPLETE;
532                 }
533
534         case SMIC_HOSED:
535                 init_smic_data(smic, smic->io);
536                 return SI_SM_HOSED;
537
538         default:
539                 if (smic_debug & SMIC_DEBUG_ENABLE) {
540                         printk(KERN_DEBUG "smic->state = %d\n", smic->state);
541                         start_error_recovery(smic, "state = UNKNOWN");
542                         return SI_SM_CALL_WITH_DELAY;
543                 }
544         }
545         smic->smic_timeout = SMIC_RETRY_TIMEOUT;
546         return SI_SM_CALL_WITHOUT_DELAY;
547 }
548
549 static int smic_detect(struct si_sm_data *smic)
550 {
551         /*
552          * It's impossible for the SMIC fnags register to be all 1's,
553          * (assuming a properly functioning, self-initialized BMC)
554          * but that's what you get from reading a bogus address, so we
555          * test that first.
556          */
557         if (read_smic_flags(smic) == 0xff)
558                 return 1;
559
560         return 0;
561 }
562
563 static void smic_cleanup(struct si_sm_data *kcs)
564 {
565 }
566
567 static int smic_size(void)
568 {
569         return sizeof(struct si_sm_data);
570 }
571
572 const struct si_sm_handlers smic_smi_handlers = {
573         .init_data         = init_smic_data,
574         .start_transaction = start_smic_transaction,
575         .get_result        = smic_get_result,
576         .event             = smic_event,
577         .detect            = smic_detect,
578         .cleanup           = smic_cleanup,
579         .size              = smic_size,
580 };