gps: dump position in i2c message
[protos/imu.git] / partition.c
1
2 /*
3  * Copyright (c) 2006-2012 by Roland Riegel <feedback@roland-riegel.de>
4  *
5  * This file is free software; you can redistribute it and/or modify
6  * it under the terms of either the GNU General Public License version 2
7  * or the GNU Lesser General Public License version 2.1, both as
8  * published by the Free Software Foundation.
9  */
10
11 #include "byteordering.h"
12 #include "partition.h"
13 #include "partition_config.h"
14 #include "sd-reader_config.h"
15
16 #include <string.h>
17
18 #if USE_DYNAMIC_MEMORY
19     #include <stdlib.h>
20 #endif
21
22 /**
23  * \addtogroup partition Partition table support
24  *
25  * Support for reading partition tables and access to partitions.
26  *
27  * @{
28  */
29 /**
30  * \file
31  * Partition table implementation (license: GPLv2 or LGPLv2.1)
32  *
33  * \author Roland Riegel
34  */
35
36 /**
37  * \addtogroup partition_config Configuration of partition table support
38  * Preprocessor defines to configure the partition support.
39  */
40
41 #if !USE_DYNAMIC_MEMORY
42 static struct partition_struct partition_handles[PARTITION_COUNT];
43 #endif
44
45 /**
46  * Opens a partition.
47  *
48  * Opens a partition by its index number and returns a partition
49  * handle which describes the opened partition.
50  *
51  * \note This function does not support extended partitions.
52  *
53  * \param[in] device_read A function pointer which is used to read from the disk.
54  * \param[in] device_read_interval A function pointer which is used to read in constant intervals from the disk.
55  * \param[in] device_write A function pointer which is used to write to the disk.
56  * \param[in] device_write_interval A function pointer which is used to write a data stream to disk.
57  * \param[in] index The index of the partition which should be opened, range 0 to 3.
58  *                  A negative value is allowed as well. In this case, the partition opened is
59  *                  not checked for existance, begins at offset zero, has a length of zero
60  *                  and is of an unknown type. Use this in case you want to open the whole device
61  *                  as a single partition (e.g. for "super floppy" use).
62  * \returns 0 on failure, a partition descriptor on success.
63  * \see partition_close
64  */
65 struct partition_struct* partition_open(device_read_t device_read, device_read_interval_t device_read_interval, device_write_t device_write, device_write_interval_t device_write_interval, int8_t index)
66 {
67     struct partition_struct* new_partition = 0;
68     uint8_t buffer[0x10];
69
70     if(!device_read || !device_read_interval || index >= 4)
71         return 0;
72
73     if(index >= 0)
74     {
75         /* read specified partition table index */
76         if(!device_read(0x01be + index * 0x10, buffer, sizeof(buffer)))
77             return 0;
78
79         /* abort on empty partition entry */
80         if(buffer[4] == 0x00)
81             return 0;
82     }
83
84     /* allocate partition descriptor */
85 #if USE_DYNAMIC_MEMORY
86     new_partition = malloc(sizeof(*new_partition));
87     if(!new_partition)
88         return 0;
89 #else
90     new_partition = partition_handles;
91     uint8_t i;
92     for(i = 0; i < PARTITION_COUNT; ++i)
93     {
94         if(new_partition->type == PARTITION_TYPE_FREE)
95             break;
96
97         ++new_partition;
98     }
99     if(i >= PARTITION_COUNT)
100         return 0;
101 #endif
102
103     memset(new_partition, 0, sizeof(*new_partition));
104
105     /* fill partition descriptor */
106     new_partition->device_read = device_read;
107     new_partition->device_read_interval = device_read_interval;
108     new_partition->device_write = device_write;
109     new_partition->device_write_interval = device_write_interval;
110
111     if(index >= 0)
112     {
113         new_partition->type = buffer[4];
114         new_partition->offset = read32(&buffer[8]);
115         new_partition->length = read32(&buffer[12]);
116     }
117     else
118     {
119         new_partition->type = 0xff;
120     }
121
122     return new_partition;
123 }
124
125 /**
126  * Closes a partition.
127  *
128  * This function destroys a partition descriptor which was
129  * previously obtained from a call to partition_open().
130  * When this function returns, the given descriptor will be
131  * invalid.
132  *
133  * \param[in] partition The partition descriptor to destroy.
134  * \returns 0 on failure, 1 on success.
135  * \see partition_open
136  */
137 uint8_t partition_close(struct partition_struct* partition)
138 {
139     if(!partition)
140         return 0;
141
142     /* destroy partition descriptor */
143 #if USE_DYNAMIC_MEMORY
144     free(partition);
145 #else
146     partition->type = PARTITION_TYPE_FREE;
147 #endif
148
149     return 1;
150 }
151
152 /**
153  * @}
154  */
155