15
#include <drivers/block_dev.h>
16
#include <drivers/flash/flash.h>
20
static int flashbdev_ioctl(struct block_dev *bdev, int cmd, void *buf,
22
static int flashbdev_read(struct block_dev *bdev, char *buffer, size_t count,
24
static int flashbdev_write(struct block_dev *bdev, char *buffer, size_t count,
27
static const struct block_dev_ops flashbdev_pio_driver = {
28
.bdo_ioctl = flashbdev_ioctl,
29
.bdo_read = flashbdev_read,
30
.bdo_write = flashbdev_write,
33
struct flash_dev *flash_create(const char *name, size_t size) {
34
struct flash_dev *flash;
35
char dev_name[FILENAME_MAX];
39
if (NULL == (flash = flash_alloc())) {
40
return err2ptr(ENOMEM);
43
memset(dev_name, 0, sizeof(dev_name));
44
snprintf(dev_name, sizeof(dev_name), "%s%d", name, flash->idx);
46
flash->bdev = block_dev_create(dev_name, &flashbdev_pio_driver, flash);
47
if (NULL == flash->bdev) {
52
flash->bdev->size = size;
54
flash->fld_word_size = 4;
55
flash->fld_aligned_word = NULL;
60
int flash_delete(struct flash_dev *dev) {
61
block_dev_destroy(dev->bdev);
67
static int flashbdev_read(struct block_dev *bdev, char *buffer, size_t count,
69
struct flash_dev *flash;
74
flash = block_dev_priv(bdev);
78
offset = bdev->block_size * blkno;
80
return flash_read(flash, offset, buffer, count);
83
static int flashbdev_write(struct block_dev *bdev, char *buffer, size_t count,
85
struct flash_dev *flash;
90
flash = block_dev_priv(bdev);
94
offset = bdev->block_size * blkno;
96
return flash_write(flash, offset, buffer, count);
99
static int flashbdev_erase(struct flash_dev *dev, uint32_t flash_base,
100
size_t len, uint32_t *err_address) {
101
uint32_t cur_off, end_addr;
106
if ((!dev->drv) || (!dev->drv->flash_erase_block)) {
114
if ((dev->size - flash_base) < len) {
115
end_addr = flash_base + dev->size;
118
end_addr = flash_base + len;
121
for (cur_off = flash_base; cur_off < end_addr; ) {
124
blk = flash_get_block_by_offset(dev, cur_off);
126
assert(cur_off == flash_get_offset_by_block(dev, blk));
128
stat = dev->drv->flash_erase_block(dev, blk);
131
*err_address = cur_off;
135
cur_off += flash_get_block_size(dev, blk);
141
static int decode_flash_cmd(int cmd) {
143
case IOCTL_GETBLKSIZE:
144
return FLASH_IOCTL_BLOCKSIZE;
145
case IOCTL_GETDEVSIZE:
146
return FLASH_IOCTL_DEVSIZE;
152
static int flashbdev_ioctl(struct block_dev *bdev, int cmd, void *buf,
154
struct flash_dev *dev;
155
struct flash_ioctl_erase *e;
156
uint32_t startpos, endpos;
157
struct flash_ioctl_devsize *ds;
158
struct flash_ioctl_devaddr *da;
159
struct flash_ioctl_blocksize *bs;
163
dev = block_dev_priv(bdev);
166
cmd = decode_flash_cmd(cmd);
169
case FLASH_IOCTL_ERASE:
170
e = (struct flash_ioctl_erase *)buf;
171
startpos = e->offset;
176
endpos = startpos + e->len - 1;
178
if (endpos > dev->size) {
182
e->flasherr = flashbdev_erase(dev, startpos, e->len, &e->err_address);
185
case FLASH_IOCTL_DEVSIZE:
186
ds = (struct flash_ioctl_devsize *)buf;
189
return (dev->size + 1);
192
ds->dev_size = dev->size + 1;
196
case FLASH_IOCTL_DEVADDR:
197
da = (struct flash_ioctl_devaddr *)buf;
207
case FLASH_IOCTL_BLOCKSIZE:
208
bs = (struct flash_ioctl_blocksize *)buf;
210
assert(dev->num_block_infos == 1);
213
return flash_get_block_size(dev, 0);
216
bs->block_size = flash_get_block_size(dev, 0);
226
#include <embox/unit.h>
227
EMBOX_UNIT_INIT(_flash_devs_init);
228
static int _flash_devs_init(void) {
229
return flash_devs_init();