
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 ihar.filipau@cadcon.de 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 ihar.filipau@cadcon.de ---
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))