2 * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
9 * - Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
11 * - Redistributions in binary form must reproduce the above copyright
\r
12 * notice, this list of conditions and the following disclaimer in the
\r
13 * documentation and/or other materials provided with the distribution.
\r
14 * - The name of the author may not be used to endorse or promote products
\r
15 * derived from this software without specific prior written permission.
\r
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
29 #include "sdc_lwext4.h"
\r
32 #include <ext4_config.h>
\r
33 #include <ext4_blockdev.h>
\r
34 #include <ext4_errno.h>
\r
36 #include <stdbool.h>
\r
44 /**@brief Block size.*/
\r
45 #define SDC_BLOCK_SIZE 512
\r
47 /**@brief MBR_block ID*/
\r
48 #define MBR_BLOCK_ID 0
\r
49 #define MBR_PART_TABLE_OFF 446
\r
51 struct part_tab_entry {
\r
58 } __attribute__((packed));
\r
60 /**@brief Partition block offset*/
\r
61 static uint32_t part_offset;
\r
63 /**@brief IO timings*/
\r
64 struct sdc_io_timings {
\r
66 uint64_t acc_bwrite;
\r
69 uint32_t cnt_bwrite;
\r
75 static struct sdc_io_timings io_timings;
\r
77 void io_timings_clear(void)
\r
79 memset(&io_timings, 0, sizeof(struct sdc_io_timings));
\r
82 const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms)
\r
84 static struct ext4_io_stats s;
\r
86 s.io_read = (((float)io_timings.acc_bread * 100.0) / time_sum_ms);
\r
87 s.io_read /= 1000.0;
\r
89 s.io_write = (((float)io_timings.acc_bwrite * 100.0) / time_sum_ms);
\r
90 s.io_write /= 1000.0;
\r
92 s.cpu = 100.0 - s.io_read - s.io_write;
\r
97 /**********************BLOCKDEV INTERFACE**************************************/
\r
98 static int sdc_open(struct ext4_blockdev *bdev);
\r
99 static int sdc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
\r
101 static int sdc_bwrite(struct ext4_blockdev *bdev, const void *buf,
\r
102 uint64_t blk_id, uint32_t blk_cnt);
\r
103 static int sdc_close(struct ext4_blockdev *bdev);
\r
105 /******************************************************************************/
\r
106 EXT4_BLOCKDEV_STATIC_INSTANCE(_sdc, SDC_BLOCK_SIZE, 0, sdc_open, sdc_bread,
\r
107 sdc_bwrite, sdc_close);
\r
109 /******************************************************************************/
\r
110 EXT4_BCACHE_STATIC_INSTANCE(_sdc_cache, CONFIG_BLOCK_DEV_CACHE_SIZE,
\r
111 EXT_LOGICAL_BLOCK_SIZE);
\r
113 /******************************************************************************/
\r
115 static int sdc_open(struct ext4_blockdev *bdev)
\r
119 static uint8_t mbr[512];
\r
120 struct part_tab_entry *part0;
\r
122 sdcStart(&SDCD1, NULL);
\r
124 if (sdcConnect(&SDCD1) != HAL_SUCCESS)
\r
127 if (sdcRead(&SDCD1, 0, mbr, 1) != HAL_SUCCESS)
\r
130 part0 = (struct part_tab_entry *)(mbr + MBR_PART_TABLE_OFF);
\r
132 part_offset = part0->first_lba;
\r
133 _sdc.ph_bcnt = SDCD1.capacity * SDC_BLOCK_SIZE;
\r
138 static int sdc_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
\r
143 uint64_t v = tim_get_us();
\r
145 status = sdcRead(&SDCD1, blk_id, buf, blk_cnt);
\r
146 if (status != HAL_SUCCESS)
\r
149 io_timings.acc_bread += tim_get_us() - v;
\r
150 io_timings.cnt_bread++;
\r
151 io_timings.av_bread = io_timings.acc_bread / io_timings.cnt_bread;
\r
156 static int sdc_bwrite(struct ext4_blockdev *bdev, const void *buf,
\r
157 uint64_t blk_id, uint32_t blk_cnt)
\r
161 uint64_t v = tim_get_us();
\r
163 status = sdcWrite(&SDCD1, blk_id, buf, blk_cnt);
\r
164 if (status != HAL_SUCCESS)
\r
167 io_timings.acc_bwrite += tim_get_us() - v;
\r
168 io_timings.cnt_bwrite++;
\r
169 io_timings.av_bwrite = io_timings.acc_bwrite / io_timings.cnt_bwrite;
\r
174 static int sdc_close(struct ext4_blockdev *bdev)
\r
180 /******************************************************************************/
\r
182 struct ext4_bcache *sdc_cache_get(void) { return &_sdc_cache; }
\r
184 struct ext4_blockdev *sdc_bdev_get(void) { return &_sdc; }
\r