Hi Simon,

> Can you please resend this inline with patman / git send-email, rather
> than as an attachment?

I'm behind a corporate firewall - I can't SMTP/IMAP - on which git
send-email relies. (And I'm sure you do not want me to send patches
with Outlook.)

At most, without attachments, I can post in-line what patman wanted to send:

P.S. But here a pastebin - http://pastebin.com/JirJw9NX - just in case.

P.P.S. Do not blame me for the formatting, inconsistent with the rest of
the file: patman has insisted.



>From 8d05ccdea2fa533d6427acfe5b78300984344d5e Mon Sep 17 00:00:00 2001
From: Ihar Filipau <[email protected]>
Date: Tue, 12 Jul 2016 13:27:02 +0200
Subject: [PATCH] storage device support for ub_dev_write

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.


Signed-off-by: Ihar Filipau <[email protected]>
---

 api/api.c           | 90 +++++++++++++++++++++++++++++++++++------------------
 api/api_private.h   |  1 +
 api/api_storage.c   | 21 +++++++++++++
 examples/api/glue.c | 20 ++++++++++++
 4 files changed, 102 insertions(+), 30 deletions(-)

diff --git a/api/api.c b/api/api.c
index 8a1433a..2ce5d07 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:
+ *
+ *    int API_dev_write(
+ *         struct device_info *di,
+ *         void *buf,
+ *         int *len
+ *    )
+ *
+ * buf:        ptr to buffer with data to write
  *
- * buf:        ptr to buffer from where to get the data to send
+ * 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)
  *
- * len: length of packet to be sent (in bytes)
+ * 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,45 @@ 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..efb23c1 100644
--- a/api/api_storage.c
+++ b/api/api_storage.c
@@ -365,3 +365,24 @@ lbasize_t dev_read_stor(void *cookie, void *buf,
lbasize_t len, lbastart_t start

        return dd->block_read(dd, start, len, buf);
 }
+
+lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len,
+               lbastart_t start)
+{
+       int type;
+       block_dev_desc_t *dd = (block_dev_desc_t *)cookie;
+
+       type = dev_stor_type(dd);
+       if (type == ENUM_MAX)
+               return 0;
+
+       if (!dev_stor_is_valid(type, dd))
+               return 0;
+
+       if ((dd->block_write) == NULL) {
+               debugf("no block_write() for device 0x%08x\n", cookie);
+               return 0;
+       }
+
+       return dd->block_write(dev_stor_index(dd), start, len, buf);
+}
diff --git a/examples/api/glue.c b/examples/api/glue.c
index 8aabf32..1a1b69b 100644
--- a/examples/api/glue.c
+++ b/examples/api/glue.c
@@ -290,6 +290,26 @@ int ub_dev_read(int handle, void *buf, lbasize_t
len, lbastart_t start,
        return err;
 }

+int ub_dev_write(int handle, void *buf, lbasize_t len, lbastart_t start,
+               lbasize_t *rlen)
+{
+       struct device_info *di;
+       lbasize_t act_len;
+       int err = 0;
+
+       if (!dev_stor_valid(handle))
+               return API_ENODEV;
+
+       di = &devices[handle];
+       if (!syscall(API_DEV_WRITE, &err, di, buf, &len, &start, &act_len))
+               return API_ESYSC;
+
+       if (!err && rlen)
+               *rlen = act_len;
+
+       return err;
+}
+
 static int dev_net_valid(int handle)
 {
        if (!dev_valid(handle))
-- 
1.9.1
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to