Signed-off-by: Eric Nelson <e...@nelint.com>
---
 drivers/block/Makefile      |  1 +
 drivers/block/cache_block.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
 include/part.h              | 65 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100644 drivers/block/cache_block.c

diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index b5c7ae1..056a48b 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_IDE_SIL680) += sil680.o
 obj-$(CONFIG_SANDBOX) += sandbox.o
 obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
+obj-$(CONFIG_BLOCK_CACHE) += cache_block.o
diff --git a/drivers/block/cache_block.c b/drivers/block/cache_block.c
new file mode 100644
index 0000000..12e60ac
--- /dev/null
+++ b/drivers/block/cache_block.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) Nelson Integration, LLC 2016
+ * Author: Eric Nelson<e...@nelint.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <part.h>
+
+#define MAX_CACHEBLOCKS 8
+
+static int cache_iftype = -1;
+static int cache_devnum = -1;
+static lbaint_t cache_start = -1;
+static lbaint_t cache_blkcnt = -1;
+static unsigned long cache_blksz;
+static void *cache;
+
+int cache_block_read(int iftype, int dev,
+                    lbaint_t start, lbaint_t blkcnt,
+                    unsigned long blksz, void *buffer)
+{
+       if ((iftype == cache_iftype) &&
+           (dev == cache_devnum) &&
+           (start == cache_start) &&
+           (blkcnt <= cache_blkcnt) &&
+           (blksz == cache_blksz) &&
+           (cache != 0)) {
+               memcpy(buffer, cache, blksz*blkcnt);
+               return 1;
+       }
+       return 0;
+}
+
+void cache_block_fill(int iftype, int dev,
+                     lbaint_t start, lbaint_t blkcnt,
+                     unsigned long blksz, void const *buffer)
+{
+       lbaint_t bytes;
+
+       /* don't cache big stuff */
+       if (blkcnt > MAX_CACHEBLOCKS)
+               return;
+
+       bytes = blksz*blkcnt;
+       if (cache != 0) {
+               if (bytes != (cache_blksz*cache_blkcnt)) {
+                       free(cache);
+                       cache = malloc(blksz*blkcnt);
+                       if (!cache)
+                               return;
+               } /* change in size */
+       } else {
+               cache = malloc(blksz*blkcnt);
+               if (!cache)
+                       return;
+       }
+       memcpy(cache, buffer, bytes);
+       cache_iftype = iftype;
+       cache_devnum = dev;
+       cache_start = start;
+       cache_blkcnt = blkcnt;
+       cache_blksz = blksz;
+}
+
+void cache_block_invalidate(int iftype, int dev)
+{
+       cache_iftype = -1;
+       if (cache) {
+               free(cache);
+               cache = 0;
+       }
+}
diff --git a/include/part.h b/include/part.h
index 6d8f520..21f820f 100644
--- a/include/part.h
+++ b/include/part.h
@@ -369,4 +369,69 @@ int gpt_verify_partitions(struct blk_desc *dev_desc,
                          gpt_header *gpt_head, gpt_entry **gpt_pte);
 #endif
 
+#ifdef CONFIG_BLOCK_CACHE
+/**
+ * cache_block_read() - attempt to read a set of blocks from cache
+ *
+ * @param iftype - IF_TYPE_x for type of device
+ * @param dev - device index of particular type
+ * @param start - starting block number
+ * @param blkcnt - number of blocks to read
+ * @param blksz - size in bytes of each block
+ * @param buf - buffer to contain cached data
+ *
+ * @return - '1' if block returned from cache, '0' otherwise.
+ */
+int cache_block_read
+       (int iftype, int dev,
+        lbaint_t start, lbaint_t blkcnt,
+        unsigned long blksz, void *buffer);
+
+/**
+ * cache_block_fill() - make data read from a block device available
+ * to the block cache
+ *
+ * @param iftype - IF_TYPE_x for type of device
+ * @param dev - device index of particular type
+ * @param start - starting block number
+ * @param blkcnt - number of blocks available
+ * @param blksz - size in bytes of each block
+ * @param buf - buffer containing data to cache
+ *
+ */
+void cache_block_fill
+       (int iftype, int dev,
+        lbaint_t start, lbaint_t blkcnt,
+        unsigned long blksz, void const *buffer);
+
+/**
+ * cache_block_invalidate() - discard the cache for a set of blocks
+ * because of a write or device (re)initialization.
+ *
+ * @param iftype - IF_TYPE_x for type of device
+ * @param dev - device index of particular type
+ */
+void cache_block_invalidate
+       (int iftype, int dev);
+
+#else
+
+static inline int cache_block_read
+       (int iftype, int dev,
+        lbaint_t start, lbaint_t blkcnt,
+        unsigned long blksz, void *buffer)
+{
+       return 0;
+}
+
+static inline void cache_block_fill
+       (int iftype, int dev,
+        lbaint_t start, lbaint_t blkcnt,
+        unsigned long blksz, void const *buffer) {}
+
+static inline void cache_block_invalidate
+       (int iftype, int dev) {}
+
+#endif
+
 #endif /* _PART_H */
-- 
2.6.2

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to