c285ba62908f5b8a2797123906c11624e10a5787
[libsamsung-ipc.git] / samsung-ipc / devices / aries / aries.c
1 /*
2  * This file is part of libsamsung-ipc.
3  *
4  * Copyright (C) 2011 Joerie de Gram <j.de.gram@gmail.com>
5  * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
6  * Copyright (C) 2011 Igor Almeida <igor.contato@gmail.com>
7  * Copyright (C) 2011-2014 Paul Kocialkowski <contact@paulk.fr>
8  *
9  * libsamsung-ipc is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * libsamsung-ipc is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with libsamsung-ipc.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <fcntl.h>
29 #include <sys/ioctl.h>
30 #include <sys/mman.h>
31 #include <net/if.h>
32
33 #include <samsung-ipc.h>
34 #include <ipc.h>
35
36 #include "onedram.h"
37 #include "phonet.h"
38
39 #include "xmm616.h"
40 #include "aries.h"
41
42 int aries_boot(struct ipc_client *client)
43 {
44     void *modem_image_data = NULL;
45     void *onedram_address = NULL;
46     unsigned int onedram_init;
47     unsigned int onedram_magic;
48     unsigned int onedram_deinit;
49     int onedram_fd = -1;
50     int serial_fd = -1;
51     struct timeval timeout;
52     fd_set fds;
53     unsigned char *p;
54     unsigned char *pp;
55     int rc;
56     int i;
57
58     if (client == NULL || client->handlers == NULL || client->handlers->power_on == NULL || client->handlers->power_off == NULL)
59         return -1;
60
61     ipc_client_log(client, "Starting aries modem boot");
62
63     modem_image_data = file_data_read(ARIES_MODEM_IMAGE_DEVICE, ARIES_MODEM_IMAGE_SIZE, 0x1000, 0);
64     if (modem_image_data == NULL) {
65         ipc_client_log(client, "Reading modem image data failed");
66         goto error;
67     }
68     ipc_client_log(client, "Read modem image data");
69
70     onedram_fd = open(ARIES_ONEDRAM_DEVICE, O_RDWR);
71     if (onedram_fd < 0) {
72         ipc_client_log(client, "Opening onedram failed");
73         goto error;
74     }
75     ipc_client_log(client, "Opened onedram");
76
77     rc = network_iface_down(ARIES_MODEM_IFACE, AF_PHONET, SOCK_DGRAM);
78     if (rc < 0) {
79         ipc_client_log(client, "Turning modem network iface down failed");
80         goto error;
81     }
82     ipc_client_log(client, "Turned modem network iface down");
83
84     rc = client->handlers->power_on(client->handlers->power_data);
85     if (rc < 0) {
86         ipc_client_log(client, "Powering the modem off failed");
87         goto error;
88     }
89     ipc_client_log(client, "Powered the modem off");
90
91     usleep(1000);
92
93     rc = client->handlers->power_off(client->handlers->power_data);
94     if (rc < 0) {
95         ipc_client_log(client, "Powering the modem on failed");
96         goto error;
97     }
98     ipc_client_log(client, "Powered the modem on");
99
100     serial_fd = open(ARIES_MODEM_SERIAL_DEVICE, O_RDWR | O_NDELAY);
101     if (serial_fd < 0) {
102         ipc_client_log(client, "Opening serial failed");
103         goto error;
104     }
105     ipc_client_log(client, "Opened serial");
106
107     usleep(100000);
108
109     p = (unsigned char *) modem_image_data;
110
111     rc = xmm616_psi_send(client, serial_fd, (void *) p, ARIES_PSI_SIZE);
112     if (rc < 0) {
113         ipc_client_log(client, "Sending XMM616 PSI failed");
114         goto error;
115     }
116     ipc_client_log(client, "Sent XMM616 PSI");
117
118     p += ARIES_PSI_SIZE;
119
120     onedram_init = 0;
121
122     FD_ZERO(&fds);
123     FD_SET(onedram_fd, &fds);
124
125     timeout.tv_sec = 4;
126     timeout.tv_usec = 0;
127
128     i = 0;
129     do {
130         rc = select(onedram_fd + 1, &fds, NULL, NULL, &timeout);
131         if (rc <= 0) {
132             ipc_client_log(client, "Reading onedram init failed");
133             goto error;
134         }
135
136         rc = read(onedram_fd, &onedram_init, sizeof(onedram_init));
137         if (rc < (int) sizeof(onedram_init)) {
138             ipc_client_log(client, "Reading onedram init failed");
139             goto error;
140         }
141
142         if (i++ > 50) {
143             ipc_client_log(client, "Reading onedram init failed");
144             goto error;
145         }
146     } while (onedram_init != ARIES_ONEDRAM_INIT);
147     ipc_client_log(client, "Read onedram init (0x%x)", onedram_init);
148
149     onedram_address = mmap(NULL, ARIES_ONEDRAM_MEMORY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, onedram_fd, 0);
150     if (onedram_address == NULL || onedram_address == (void *) 0xffffffff) {
151             ipc_client_log(client, "Mapping onedram to memory failed");
152             goto error;
153     }
154     ipc_client_log(client, "Mapped onedram to memory");
155
156     pp = (unsigned char *) onedram_address;
157
158     rc = xmm616_firmware_send(client, -1, (void *) pp, (void *) p, ARIES_MODEM_IMAGE_SIZE - ARIES_PSI_SIZE);
159     if (rc < 0) {
160         ipc_client_log(client, "Sending XMM616 firmware failed");
161         goto error;
162     }
163     ipc_client_log(client, "Sent XMM616 firmware");
164
165     pp = (unsigned char *) onedram_address + ARIES_ONEDRAM_NV_DATA_OFFSET;
166
167     rc = xmm616_nv_data_send(client, -1, pp);
168     if (rc < 0) {
169         ipc_client_log(client, "Sending XMM616 nv_data failed");
170         goto error;
171     }
172     ipc_client_log(client, "Sent XMM616 nv_data");
173
174     munmap(onedram_address, ARIES_ONEDRAM_MEMORY_SIZE);
175     onedram_address = NULL;
176
177     rc = ioctl(onedram_fd, ONEDRAM_REL_SEM);
178     if (rc < 0)
179         goto error;
180
181     onedram_magic = ARIES_ONEDRAM_MAGIC;
182     rc = write(onedram_fd, &onedram_magic, sizeof(onedram_magic));
183     if (rc < (int) sizeof(onedram_magic)) {
184         ipc_client_log(client, "Writing onedram magic failed");
185         goto error;
186     }
187     ipc_client_log(client, "Wrote onedram magic");
188
189     FD_ZERO(&fds);
190     FD_SET(onedram_fd, &fds);
191
192     timeout.tv_sec = 4;
193     timeout.tv_usec = 0;
194
195     i = 0;
196     do {
197         rc = select(onedram_fd + 1, &fds, NULL, NULL, &timeout);
198         if (rc <= 0) {
199             ipc_client_log(client, "Reading onedram deinit failed");
200             goto error;
201         }
202
203         rc = read(onedram_fd, &onedram_deinit, sizeof(onedram_deinit));
204         if (rc < (int) sizeof(onedram_deinit)) {
205             ipc_client_log(client, "Reading onedram deinit failed");
206             goto error;
207         }
208
209         if (i++ > 50) {
210             ipc_client_log(client, "Reading onedram deinit failed");
211             goto error;
212         }
213     } while (onedram_deinit != ARIES_ONEDRAM_DEINIT);
214     ipc_client_log(client, "Read onedram deinit (0x%x)", onedram_deinit);
215
216     rc = 0;
217     goto complete;
218
219 error:
220     rc = -1;
221
222 complete:
223     if (modem_image_data != NULL)
224         free(modem_image_data);
225
226     if (serial_fd >= 0)
227         close(serial_fd);
228
229     if (onedram_address != NULL)
230         munmap(onedram_address, ARIES_ONEDRAM_MEMORY_SIZE);
231
232     if (onedram_fd >= 0)
233         close(onedram_fd);
234
235     return rc;
236 }
237
238 int aries_fmt_send(struct ipc_client *client, struct ipc_message *message)
239 {
240     struct ipc_fmt_header header;
241     void *buffer;
242     size_t length;
243     size_t count = 0;
244     size_t chunk;
245     unsigned char *p;
246     int rc;
247
248     if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || message == NULL)
249         return -1;
250
251     ipc_fmt_header_setup(&header, message);
252
253     length = header.length;
254     buffer = calloc(1, length);
255
256     memcpy(buffer, &header, sizeof(struct ipc_fmt_header));
257
258     if (message->data != NULL && message->size > 0) {
259         p = (unsigned char *) buffer + sizeof(header);
260         memcpy(p, message->data, message->size);
261     }
262
263     ipc_client_log_send(client, message, __func__);
264
265     p = (unsigned char *) buffer;
266
267     while (count < length) {
268         chunk = length - count < ARIES_BUFFER_LENGTH ? length - count : ARIES_BUFFER_LENGTH;
269
270         rc = client->handlers->write(client->handlers->transport_data, p, chunk);
271         if (rc < 0) {
272             ipc_client_log(client, "Writing FMT data failed");
273             goto error;
274         }
275
276         count += rc;
277         p += rc;
278     }
279
280     rc = 0;
281     goto complete;
282
283 error:
284     rc = -1;
285
286 complete:
287     if (buffer != NULL)
288         free(buffer);
289
290     return rc;
291 }
292
293 int aries_fmt_recv(struct ipc_client *client, struct ipc_message *message)
294 {
295     struct ipc_fmt_header *header;
296     void *buffer;
297     size_t length;
298     size_t count = 0;
299     size_t chunk;
300     unsigned char *p;
301     int rc;
302
303     if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || message == NULL)
304         return -1;
305
306     length = ARIES_BUFFER_LENGTH;
307     buffer = calloc(1, length);
308
309     rc = client->handlers->read(client->handlers->transport_data, buffer, length);
310     if (rc < (int) sizeof(struct ipc_fmt_header)) {
311         ipc_client_log(client, "Reading FMT header failed");
312         goto error;
313     }
314
315     header = (struct ipc_fmt_header *) buffer;
316
317     ipc_fmt_message_setup(header, message);
318
319     length = header->length - sizeof(struct ipc_fmt_header);
320     if (length > 0) {
321         message->size = length;
322         message->data = calloc(1, length);
323
324         count = rc - sizeof(struct ipc_fmt_header);
325         if (count > 0) {
326             p = (unsigned char *) buffer + sizeof(struct ipc_fmt_header);
327             memcpy(message->data, p, count);
328         }
329     }
330
331     p = (unsigned char *) message->data + count;
332
333     while (count < length) {
334         chunk = length - count < ARIES_BUFFER_LENGTH ? length - count : ARIES_BUFFER_LENGTH;
335
336         rc = client->handlers->read(client->handlers->transport_data, p, chunk);
337         if (rc < 0) {
338             ipc_client_log(client, "Reading FMT data failed");
339             goto error;
340         }
341
342         count += rc;
343         p += rc;
344     }
345
346     ipc_client_log_recv(client, message, __func__);
347
348     rc = 0;
349     goto complete;
350
351 error:
352     rc = -1;
353
354 complete:
355     if (buffer != NULL)
356         free(buffer);
357
358     return rc;
359 }
360
361 int aries_rfs_send(struct ipc_client *client, struct ipc_message *message)
362 {
363     struct ipc_rfs_header header;
364     void *buffer;
365     size_t length;
366     size_t count = 0;
367     size_t chunk;
368     unsigned char *p;
369     int rc;
370
371     if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || message == NULL)
372         return -1;
373
374     ipc_rfs_header_setup(&header, message);
375
376     length = header.length;
377     buffer = calloc(1, length);
378
379     memcpy(buffer, &header, sizeof(header));
380     if (message->data != NULL && message->size > 0) {
381         p = (unsigned char *) buffer + sizeof(header);
382         memcpy(p, message->data, message->size);
383     }
384
385     ipc_client_log_send(client, message, __func__);
386
387     p = (unsigned char *) buffer;
388
389     while (count < length) {
390         chunk = length - count < ARIES_BUFFER_LENGTH ? length - count : ARIES_BUFFER_LENGTH;
391
392         rc = client->handlers->write(client->handlers->transport_data, p, chunk);
393         if (rc < 0) {
394             ipc_client_log(client, "Writing RFS data failed");
395             goto error;
396         }
397
398         count += rc;
399         p += rc;
400     }
401
402     rc = 0;
403     goto complete;
404
405 error:
406     rc = -1;
407
408 complete:
409     if (buffer != NULL)
410         free(buffer);
411
412     return rc;
413 }
414
415 int aries_rfs_recv(struct ipc_client *client, struct ipc_message *message)
416 {
417     struct ipc_rfs_header *header;
418     void *buffer;
419     size_t length;
420     size_t count = 0;
421     size_t chunk;
422     unsigned char *p;
423     int rc;
424
425     if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || message == NULL)
426         return -1;
427
428     length = ARIES_BUFFER_LENGTH;
429     buffer = calloc(1, length);
430
431     rc = client->handlers->read(client->handlers->transport_data, buffer, length);
432     if (rc < (int) sizeof(struct ipc_rfs_header)) {
433         ipc_client_log(client, "Reading RFS header failed");
434         goto error;
435     }
436
437     header = (struct ipc_rfs_header *) buffer;
438     if (header->length > ARIES_DATA_SIZE_LIMIT) {
439         ipc_client_log(client, "Invalid RFS header length: %u", header->length);
440         goto error;
441     }
442
443     ipc_rfs_message_setup(header, message);
444
445     length = header->length - sizeof(struct ipc_rfs_header);
446     if (length > 0) {
447         message->size = length;
448         message->data = calloc(1, length);
449
450         count = rc - sizeof(struct ipc_rfs_header);
451         if (count > 0) {
452             p = (unsigned char *) buffer + sizeof(struct ipc_rfs_header);
453             memcpy(message->data, p, count);
454         }
455     }
456
457     p = (unsigned char *) message->data + count;
458
459     while (count < length) {
460         chunk = length - count < ARIES_BUFFER_LENGTH ? length - count : ARIES_BUFFER_LENGTH;
461
462         rc = client->handlers->read(client->handlers->transport_data, p, chunk);
463         if (rc < 0) {
464             ipc_client_log(client, "Reading RFS data failed");
465             goto error;
466         }
467
468         count += rc;
469         p += rc;
470     }
471
472     ipc_client_log_recv(client, message, __func__);
473
474     rc = 0;
475     goto complete;
476
477 error:
478     rc = -1;
479
480 complete:
481     if (buffer != NULL)
482         free(buffer);
483
484     return rc;
485 }
486
487 int aries_open(void *data, int type)
488 {
489     struct aries_transport_data *transport_data;
490     struct sockaddr_pn *spn;
491     struct ifreq ifr;
492     int reuse;
493     int socket_rfs_magic;
494     int fd;
495     int rc;
496
497     if (data == NULL)
498         return -1;
499
500     transport_data = (struct aries_transport_data *) data;
501     memset(data, 0, sizeof(struct aries_transport_data));
502
503     spn = &transport_data->spn;
504
505     memset(&ifr, 0, sizeof(ifr));
506     strncpy(ifr.ifr_name, ARIES_MODEM_IFACE, IFNAMSIZ);
507
508     spn->spn_family = AF_PHONET;
509     spn->spn_dev = 0;
510
511     switch (type) {
512         case IPC_CLIENT_TYPE_FMT:
513             spn->spn_resource = ARIES_MODEM_FMT_SPN;
514             break;
515         case IPC_CLIENT_TYPE_RFS:
516             spn->spn_resource = ARIES_MODEM_RFS_SPN;
517             break;
518         default:
519             break;
520     }
521
522     fd = socket(AF_PHONET, SOCK_DGRAM, 0);
523     if (fd < 0)
524         return -1;
525
526     rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, IFNAMSIZ);
527     if (rc < 0)
528         return -1;
529
530     rc = ioctl(fd, SIOCGIFINDEX, &ifr);
531     if (rc < 0)
532         return -1;
533
534     reuse = 1;
535     rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
536     if (rc < 0)
537         return -1;
538
539     rc = bind(fd, (const struct sockaddr *) spn, sizeof(struct sockaddr_pn));
540     if (rc < 0)
541         return -1;
542
543     transport_data->fd = fd;
544
545     if (type == IPC_CLIENT_TYPE_RFS)
546     {
547         socket_rfs_magic = ARIES_SOCKET_RFS_MAGIC;
548         rc = setsockopt(fd, SOL_SOCKET, SO_IPC_RFS, &socket_rfs_magic, sizeof(socket_rfs_magic));
549         if (rc < 0)
550             return -1;
551     }
552
553     rc = network_iface_up(ARIES_MODEM_IFACE, AF_PHONET, SOCK_DGRAM);
554     if (rc < 0)
555         return -1;
556
557     return 0;
558 }
559
560 int aries_close(void *data)
561 {
562     struct aries_transport_data *transport_data;
563     int fd;
564
565     if (data == NULL)
566         return -1;
567
568     transport_data = (struct aries_transport_data *) data;
569
570     fd = transport_data->fd;
571     if (fd < 0)
572         return -1;
573
574     transport_data->fd = -1;
575     close(fd);
576
577     return 0;
578 }
579
580 int aries_read(void *data, void *buffer, size_t length)
581 {
582     struct aries_transport_data *transport_data;
583     int spn_size;
584     int fd;
585     int rc;
586
587     if (data == NULL || buffer == NULL || length == 0)
588         return -1;
589
590     transport_data = (struct aries_transport_data *) data;
591
592     fd = transport_data->fd;
593     if (fd < 0)
594         return -1;
595
596     spn_size = sizeof(struct sockaddr_pn);
597
598     rc = recvfrom(fd, buffer, length, 0, (struct sockaddr *) &transport_data->spn, &spn_size);
599
600     return rc;
601 }
602
603 int aries_write(void *data, const void *buffer, size_t length)
604 {
605     struct aries_transport_data *transport_data;
606     int spn_size;
607     int fd;
608     int rc;
609
610     if (data == NULL || buffer == NULL || length == 0)
611         return -1;
612
613     transport_data = (struct aries_transport_data *) data;
614
615     fd = transport_data->fd;
616     if (fd < 0)
617         return -1;
618
619     spn_size = sizeof(struct sockaddr_pn);
620
621     rc = sendto(fd, buffer, length, 0, (const struct sockaddr *) &transport_data->spn, spn_size);
622
623     return rc;
624 }
625
626 int aries_poll(void *data, struct timeval *timeout)
627 {
628     struct aries_transport_data *transport_data;
629     fd_set fds;
630     int fd;
631     int rc;
632
633     if (data == NULL)
634         return -1;
635
636     transport_data = (struct aries_transport_data *) data;
637
638     fd = transport_data->fd;
639     if (fd < 0)
640         return -1;
641
642     FD_ZERO(&fds);
643     FD_SET(fd, &fds);
644
645     rc = select(fd + 1, &fds, NULL, NULL, timeout);
646
647     return rc;
648 }
649
650 int aries_power_on(void *data)
651 {
652     char buffer[] = "on\n";
653     int value;
654     int rc;
655
656     value = sysfs_value_read(ARIES_MODEMCTL_STATUS_SYSFS);
657     if (value < 0)
658         return -1;
659
660     // The modem is already on
661     if (value == 1)
662         return 0;
663
664     rc = sysfs_string_write(ARIES_MODEMCTL_CONTROL_SYSFS, (char *) &buffer, strlen(buffer));
665     if (rc < 0)
666         return -1;
667
668     return 0;
669 }
670
671 int aries_power_off(void *data)
672 {
673     char buffer[] = "off\n";
674     int value;
675     int rc;
676
677     value = sysfs_value_read(ARIES_MODEMCTL_STATUS_SYSFS);
678     if (value < 0)
679         return -1;
680
681     // The modem is already off
682     if (value == 0)
683         return 0;
684
685     rc = sysfs_string_write(ARIES_MODEMCTL_CONTROL_SYSFS, (char *) &buffer, strlen(buffer));
686     if (rc < 0)
687         return -1;
688
689     return 0;
690 }
691
692 int aries_data_create(void **transport_data, void **power_data,
693     void **gprs_data)
694 {
695     if (transport_data == NULL)
696         return -1;
697
698     *transport_data = calloc(1, sizeof(struct aries_transport_data));
699
700     return 0;
701 }
702
703 int aries_data_destroy(void *transport_data, void *power_data, void *gprs_data)
704 {
705     if (transport_data == NULL)
706         return -1;
707
708     free(transport_data);
709
710     return 0;
711 }
712
713 int aries_gprs_activate(void *data, unsigned int cid)
714 {
715     int rc;
716
717     rc = sysfs_value_write(ARIES_MODEM_PDP_ACTIVATE_SYSFS, cid);
718     if (rc < 0)
719         return -1;
720
721     return 0;
722 }
723
724 int aries_gprs_deactivate(void *data, unsigned int cid)
725 {
726     int rc;
727
728     rc = sysfs_value_write(ARIES_MODEM_PDP_DEACTIVATE_SYSFS, cid);
729     if (rc < 0)
730         return -1;
731
732     return 0;
733 }
734
735 char *aries_gprs_get_iface(unsigned int cid)
736 {
737     char *iface = NULL;
738     struct ifreq ifr;
739     int fd;
740     int rc;
741     int i;
742
743     memset(&ifr, 0, sizeof(ifr));
744
745     fd = socket(AF_PHONET, SOCK_DGRAM, 0);
746     if (fd < 0)
747         return NULL;
748
749     for (i = (ARIES_GPRS_IFACE_COUNT - 1); i >= 0; i--) {
750         sprintf(ifr.ifr_name, "%s%d", ARIES_GPRS_IFACE_PREFIX, i);
751         rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
752         if (rc < 0 || ifr.ifr_flags & IFF_UP) {
753             continue;
754         } else {
755             asprintf(&iface, "%s%d", ARIES_GPRS_IFACE_PREFIX, i);
756             return iface;
757         }
758     }
759
760     return NULL;
761 }
762
763 int aries_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
764 {
765     if (capabilities == NULL)
766         return -1;
767
768     capabilities->cid_count = ARIES_GPRS_IFACE_COUNT;
769
770     return 0;
771 }
772
773 struct ipc_client_ops aries_fmt_ops = {
774     .boot = aries_boot,
775     .send = aries_fmt_send,
776     .recv = aries_fmt_recv,
777 };
778
779 struct ipc_client_ops aries_rfs_ops = {
780     .boot = NULL,
781     .send = aries_rfs_send,
782     .recv = aries_rfs_recv,
783 };
784
785 struct ipc_client_handlers aries_handlers = {
786     .open = aries_open,
787     .close = aries_close,
788     .read = aries_read,
789     .write = aries_write,
790     .poll = aries_poll,
791     .transport_data = NULL,
792     .power_on = aries_power_on,
793     .power_off = aries_power_off,
794     .power_data = NULL,
795     .gprs_activate = aries_gprs_activate,
796     .gprs_deactivate = aries_gprs_deactivate,
797     .gprs_data = NULL,
798     .data_create = aries_data_create,
799     .data_destroy = aries_data_destroy,
800 };
801
802 struct ipc_client_gprs_specs aries_gprs_specs = {
803     .gprs_get_iface = aries_gprs_get_iface,
804     .gprs_get_capabilities = aries_gprs_get_capabilities,
805 };
806
807 struct ipc_client_nv_data_specs aries_nv_data_specs = {
808     .nv_data_path = XMM616_NV_DATA_PATH,
809     .nv_data_md5_path = XMM616_NV_DATA_MD5_PATH,
810     .nv_data_backup_path = XMM616_NV_DATA_BACKUP_PATH,
811     .nv_data_backup_md5_path = XMM616_NV_DATA_BACKUP_MD5_PATH,
812     .nv_data_secret = XMM616_NV_DATA_SECRET,
813     .nv_data_size = XMM616_NV_DATA_SIZE,
814     .nv_data_chunk_size = XMM616_NV_DATA_CHUNK_SIZE,
815 };
816
817 // vim:ts=4:sw=4:expandtab