Hi All!
I have stumbled upon the lack of support for storage devices in API's
ub_dev_write()/API_dev_write() functions. Currently the function
supports only the network devices.
I have implemented the support for the storage by adapting the code
from API_dev_read() function, and added the ub_dev_write() to the
glue.c. Interface for the network devices is unchanged.
I could only test the ub_dev_write() for storage, but my application
doesn't use the ub_dev_send() thus I can't test it (but 99% sure that
it still works).
The patch is attached (should apply cleanly to the current git master
git.denx.de/u-boot.git).
Comments are welcome. Applying it to the git master is even more so.
--
Pink Panther's To Do list:
- To do
- To do
- To do, to do, to do, to do, to d
From 4c6ac1f902a5ff185bad992ac1e420e53c7d Mon Sep 17 00:00:00 2001
From: Ihar Filipau
Date: Wed, 6 Jul 2016 15:35:19 +0200
Subject: [PATCH] storage device support for ub_dev_write
---
api/api.c | 89 +++--
api/api_private.h | 1 +
api/api_storage.c | 19
examples/api/glue.c | 20
4 files changed, 99 insertions(+), 30 deletions(-)
diff --git a/api/api.c b/api/api.c
index 8a1433a..19c24b1 100644
--- a/api/api.c
+++ b/api/api.c
@@ -295,28 +295,44 @@ static int API_dev_close(va_list ap)
/*
- * Notice: this is for sending network packets only, as U-Boot does not
- * support writing to storage at the moment (12.2007)
+ * pseudo signature, storage:
*
- * pseudo signature:
+ *int API_dev_write(
+ * struct device_info *di,
+ * void *buf,
+ * lbasize_t *len,
+ * lbastart_t *start,
+ * lbasize_t *act_len
+ *)
*
- * int API_dev_write(
- * struct device_info *di,
- * void *buf,
- * int *len
- * )
+ * pseudo signature, net:
*
- * buf: ptr to buffer from where to get the data to send
+ *int API_dev_write(
+ * struct device_info *di,
+ * void *buf,
+ * int *len
+ *)
*
- * len: length of packet to be sent (in bytes)
+ * buf: ptr to buffer with data to write
+ *
+ * len: length to be written
+ * - network: len of packet to write (in bytes)
+ * - storage: # of blocks to write (can vary in size depending on define)
+ *
+ * start: start block (only used for storage devices, ignored for
+ *network)
+ *
+ * act_len: ptr to where to put the len actually written
*
*/
static int API_dev_write(va_list ap)
{
struct device_info *di;
void *buf;
- int *len;
- int err = 0;
+ lbasize_t *len_stor, *act_len_stor;
+ lbastart_t *start;
+ int *len_net;
+ int ret = 0;
/* 1. arg is ptr to the device_info struct */
di = (struct device_info *)va_arg(ap, uintptr_t);
@@ -328,31 +344,44 @@ static int API_dev_write(va_list ap)
if (di->cookie == NULL)
return API_ENODEV;
- /* 2. arg is ptr to buffer from where to get data to write */
+ /* 2. arg is ptr to buffer from where to put the read data */
buf = (void *)va_arg(ap, uintptr_t);
if (buf == NULL)
return API_EINVAL;
- /* 3. arg is length of buffer */
- len = (int *)va_arg(ap, uintptr_t);
- if (len == NULL)
- return API_EINVAL;
- if (*len <= 0)
- return API_EINVAL;
+ if (di->type & DEV_TYP_STOR) {
+ /* 3. arg - ptr to var with # of blocks to read */
+ len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
+ if (!len_stor)
+ return API_EINVAL;
+ if (*len_stor <= 0)
+ return API_EINVAL;
- if (di->type & DEV_TYP_STOR)
- /*
- * write to storage is currently not supported by U-Boot:
- * no storage device implements block_write() method
- */
- return API_ENODEV;
+ /* 4. arg - ptr to var with start block */
+ start = (lbastart_t *)va_arg(ap, uintptr_t);
- else if (di->type & DEV_TYP_NET)
- err = dev_write_net(di->cookie, buf, *len);
- else
- err = API_ENODEV;
+ /* 5. arg - ptr to var where to put the len actually read */
+ act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
+ if (!act_len_stor)
+ return API_EINVAL;
- return err;
+ *act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, *start);
+
+ } else if (di->type & DEV_TYP_NET) {
+
+ /* 3. arg points to the var with length of packet to read */
+ len_net = (int *)va_arg(ap, uintptr_t);
+ if (!len_net)
+ return API_EINVAL;
+ if (*len_net <= 0)
+ return API_EINVAL;
+
+ ret = dev_write_net(di->cookie, buf, *len_net);
+
+ } else
+ return API_ENODEV;
+
+ return ret;
}
diff --git a/api/api_private.h b/api/api_private.h
index a8866ef..86d45bc 100644
--- a/api/api_private.h
+++ b/api/api_private.h
@@ -23,6 +23,7 @@ int dev_close_stor(void *);
int dev_close_net(void *);
lbasize_t dev_read_stor(void *, void *, lbasize_t, lbastart_t);
+lbasize_t dev_write_stor(void *, void *, lbasize_t, lbastart_t);
int dev_read_net(void *, void *, int);
int dev_write_net(void *, void *, int);
diff --git a/api/api_storage.c b/api/api_storage.c
index d425a9a..967f0da 100644
--- a/api/api_storage.c
+++